Issues (141)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

formats/timeline/SRF_Timeline.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Print query results in interactive timelines.
4
 *
5
 * @file SRF_Timeline.php
6
 * @ingroup SemanticResultFormats
7
 *
8
 * @author Markus Krötzsch
9
 *
10
 * FIXME: this code is just insane; rewrite from 0 is probably the only way to get it right
11
 */
12
13
/**
14
 * Result printer for timeline data.
15
 *
16
 * @ingroup SemanticResultFormats
17
 */
18
class SRFTimeline extends SMWResultPrinter {
19
20
	protected $m_tlstart = '';  // name of the start-date property if any
21
	protected $m_tlend = '';  // name of the end-date property if any
22
	protected $m_tlsize = ''; // CSS-compatible size (such as 400px)
23
	protected $m_tlbands = ''; // array of band IDs (MONTH, YEAR, ...)
24
	protected $m_tlpos = ''; // position identifier (start, end, today, middle)
25
	protected $mTemplate;
26
	protected $mNamedArgs;
27
28
	/**
29
	 * @see SMWResultPrinter::handleParameters
30
	 *
31
	 * @since 1.6.3
32
	 *
33
	 * @param array $params
34
	 * @param $outputmode
35
	 */
36 1
	protected function handleParameters( array $params, $outputmode ) {
37 1
		parent::handleParameters( $params, $outputmode );
38
39 1
		$this->mTemplate = trim( $params['template'] );
40 1
		$this->mNamedArgs = $params['named args'];
41 1
		$this->m_tlstart = smwfNormalTitleDBKey( $params['timelinestart'] );
42 1
		$this->m_tlend = smwfNormalTitleDBKey( $params['timelineend'] );
43 1
		$this->m_tlbands = $params['timelinebands'];
44 1
		$this->m_tlpos = strtolower( trim( $params['timelineposition'] ) );
45
46
		// str_replace makes sure this is only one value, not mutliple CSS fields (prevent CSS attacks)
47
		// / FIXME: this is either unsafe or redundant, since Timeline is Wiki-compatible. If the JavaScript makes user inputs to CSS then it is bad even if we block this injection path.
48 1
		$this->m_tlsize = htmlspecialchars( str_replace( ';', ' ', strtolower( $params['timelinesize'] ) ) );
49 1
	}
50
51
	public function getName() {
52
		// Give grep a chance to find the usages:
53
		// srf_printername_timeline, srf_printername_eventline
54
		return wfMessage( 'srf_printername_' . $this->mFormat )->text();
55
	}
56
57 1
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
58
59 1
		SMWOutputs::requireHeadItem( SMW_HEADER_STYLE );
60 1
		SMWOutputs::requireResource( 'ext.srf.timeline' );
61
62 1
		$isEventline = 'eventline' == $this->mFormat;
63 1
		$id = uniqid();
64
65 1
		if ( !$isEventline && ( $this->m_tlstart == '' ) ) { // seek defaults
66 1
			foreach ( $res->getPrintRequests() as $pr ) {
67 1
				if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) && ( $pr->getTypeID() == '_dat' ) ) {
68 1
					$dataValue = $pr->getData();
69
70 1
					$date_value = $dataValue->getDataItem()->getLabel();
71
72 1
					if ( ( $this->m_tlend == '' ) && ( $this->m_tlstart != '' ) &&
73 1
						( $this->m_tlstart != $date_value ) ) {
74
						$this->m_tlend = $date_value;
75 1
					} elseif ( ( $this->m_tlstart == '' ) && ( $this->m_tlend != $date_value ) ) {
76 1
						$this->m_tlstart = $date_value;
77
					}
78
				}
79
			}
80
		}
81
82
		// print header
83 1
		$result = "<div id=\"smwtimeline-$id\" class=\"smwtimeline is-disabled\" style=\"height: $this->m_tlsize\">";
84 1
		$result .= '<span class="smw-overlay-spinner medium" style="top:40%; transform: translate(-50%, -50%);"></span>';
85
86 1
		foreach ( $this->m_tlbands as $band ) {
87 1
			$result .= '<span class="smwtlband" style="display:none;">' . htmlspecialchars( $band ) . '</span>';
88
			// just print any "band" given, the JavaScript will figure out what to make of it
89
		}
90
91
		// print all result rows
92 1
		if ( ( $this->m_tlstart != '' ) || $isEventline ) {
93 1
			$result .= $this->getEventsHTML( $res, $outputmode, $isEventline );
94
		}
95
		// no further results displayed ...
96
97
		// print footer
98 1
		$result .= '</div>';
99
100
		// yes, our code can be viewed as HTML if requested, no more parsing needed
101 1
		$this->isHTML = $outputmode == SMW_OUTPUT_HTML;
102
103 1
		return $result;
104
	}
105
106
	/**
107
	 * Returns the HTML for the events.
108
	 *
109
	 * @since 1.5.3
110
	 *
111
	 * @param SMWQueryResult $res
112
	 * @param $outputmode
113
	 * @param boolean $isEventline
114
	 *
115
	 * @return string
116
	 */
117 1
	protected function getEventsHTML( SMWQueryResult $res, $outputmode, $isEventline ) {
118 1
		global $curarticle, $cururl; // why not, code flow has reached max insanity already
119
120 1
		$positions = []; // possible positions, collected to select one for centering
121 1
		$curcolor = 0; // color cycling is used for eventline
122
123 1
		$result = '';
124
125 1
		$output = false; // true if output for the popup was given on current line
126 1
		if ( $isEventline ) {
127
			$events = [];
128
		} // array of events that are to be printed
129
130 1
		while ( $row = $res->getNext() ) { // Loop over the objcts (pages)
131 1
			$hastime = false; // true as soon as some startdate value was found
132 1
			$hastitle = false; // true as soon as some label for the event was found
133 1
			$curdata = ''; // current *inner* print data (within some event span)
134 1
			$curmeta = ''; // current event meta data
135 1
			$cururl = '';
136 1
			$curarticle = ''; // label of current article, if it was found; needed only for eventline labeling
137 1
			$first_col = true;
138
139 1
			if ( $this->mTemplate != '' ) {
140
				$this->hasTemplates = true;
141
				$template_text = '';
142
				$i = 0;
143
			}
144
145 1
			foreach ( $row as $field ) { // Loop over the returned properties
146 1
				$first_value = true;
147 1
				$pr = $field->getPrintRequest();
148 1
				$dataValue = $pr->getData();
149
150 1
				if ( $dataValue == '' ) {
151 1
					$date_value = null;
152
				} else {
153 1
					$date_value = $dataValue->getDataItem()->getLabel();
154
				}
155
156 1
				while ( ( $object = $field->getNextDataValue() ) !== false ) { // Loop over property values
157 1
					$event = $this->handlePropertyValue(
158 1
						$object,
159
						$outputmode,
160
						$pr,
161
						$first_col,
162
						$hastitle,
163
						$hastime,
164
						$first_value,
165
						$isEventline,
166
						$curmeta,
167
						$curdata,
168
						$date_value,
169
						$output,
170
						$positions
171
					);
172
173 1
					if ( $this->mTemplate != '' ) {
174
						$template_text .= '|' . ( $this->mNamedArgs ? '?' . $field->getPrintRequest()->getLabel(
0 ignored issues
show
The variable $template_text does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
175
								) : $i + 1 ) . '=';
0 ignored issues
show
The variable $i does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
176
						if ( !$first_value ) {
177
							$template_text .= ', ';
178
						}
179
						$template_text .= $object->getShortText( SMW_OUTPUT_WIKI, $this->getLinker( $first_value ) );
180
						$i++;
181
					}
182
183 1
					if ( $event !== false ) {
184
						$events[] = $event;
185
					}
186
187 1
					$first_value = false;
188
				}
189
190 1
				if ( $output ) {
191 1
					$curdata .= '<br />';
192
				}
193
194 1
				$output = false;
195 1
				$first_col = false;
196
			}
197
198 1
			if ( $this->mTemplate != '' ) {
199
				$curdata = '{{' . $this->mTemplate . $template_text . '}}';
200
			}
201
202 1
			if ( $hastime ) {
203 1
				$result .= Html::rawElement(
204 1
					'span',
205 1
					[ 'class' => 'smwtlevent', 'style' => 'display:none;' ],
206 1
					$curmeta . Html::element(
207 1
						'span',
208 1
						[ 'class' => 'smwtlcoloricon' ],
209 1
						$curcolor
210 1
					) . $curdata
211
				);
212
			}
213
214 1
			if ( $isEventline ) {
215
				foreach ( $events as $event ) {
216
					$result .= '<span class="smwtlevent" style="display:none;" ><span class="smwtlstart">' . $event[0] . '</span><span class="smwtlurl">' . $curarticle . '</span><span class="smwtlcoloricon">' . $curcolor . '</span>';
217
					if ( $curarticle != '' ) {
218
						$result .= '<span class="smwtlprefix">' . $curarticle . ' </span>';
219
					}
220
					$result .= $curdata . '</span>';
221
					$positions[$event[2]] = $event[0];
222
				}
223
				$events = [];
224
				$curcolor = ( $curcolor + 1 ) % 10;
225
			}
226
		}
227
228 1
		if ( count( $positions ) > 0 ) {
229 1
			ksort( $positions );
230 1
			$positions = array_values( $positions );
231
232 1
			switch ( $this->m_tlpos ) {
233 1
				case 'start':
234
					$result .= '<span class="smwtlposition" style="display:none;" >' . $positions[0] . '</span>';
235
					break;
236 1
				case 'end':
237
					$result .= '<span class="smwtlposition" style="display:none;" >' . $positions[count(
238
							$positions
239
						) - 1] . '</span>';
240
					break;
241 1
				case 'today':
242
					break; // default
243 1
				case 'middle':
244
				default:
245 1
					$result .= '<span class="smwtlposition" style="display:none;" >' . $positions[ceil(
246 1
							count( $positions ) / 2
247 1
						) - 1] . '</span>';
248 1
					break;
249
			}
250
		}
251
252 1
		return $result;
253
	}
254
255
	/**
256
	 * Hanldes a single property value. Returns an array with data for a single event or false.
257
	 *
258
	 * FIXME: 13 arguments, of which a whole bunch are byref... not a good design :)
259
	 *
260
	 * @since 1.5.3
261
	 *
262
	 * @param SMWDataValue $object
263
	 * @param $outputmode
264
	 * @param SMWPrintRequest $pr
265
	 * @param boolean $first_col
266
	 * @param boolean &$hastitle
267
	 * @param boolean &$hastime
268
	 * @param boolean $first_value
269
	 * @param boolean $isEventline
270
	 * @param string &$curmeta
271
	 * @param string &$curdata
272
	 * @param &$date_value
273
	 * @param boolean &$output
274
	 * @param array &$positions
275
	 *
276
	 * @return false or array
277
	 */
278 1
	protected function handlePropertyValue( SMWDataValue $object, $outputmode, SMWPrintRequest $pr, $first_col,
279
		&$hastitle, &$hastime, $first_value, $isEventline, &$curmeta, &$curdata, $date_value, &$output, array &$positions ) {
280 1
		global $curarticle, $cururl;
281
282 1
		$event = false;
283
284 1
		$l = $this->getLinker( $first_col );
285
286 1
		if ( !$hastitle && $object->getTypeID(
287 1
			) != '_wpg' ) { // "linking" non-pages in title positions confuses timeline scripts, don't try this
288
			$l = null;
289
		}
290
291 1
		if ( $object->getTypeID() == '_wpg' ) { // use shorter "LongText" for wikipage
292 1
			$objectlabel = $object->getLongText( $outputmode, $l );
293
		} else {
294 1
			$objectlabel = $object->getShortText( $outputmode, $l );
295
		}
296
297 1
		$urlobject = ( $l !== null );
298 1
		$header = '';
299
300 1
		if ( $first_value ) {
301
			// find header for current value:
302 1
			if ( $this->mShowHeaders && ( '' != $pr->getLabel() ) ) {
303 1
				$header = $pr->getText( $outputmode, $this->mLinker ) . ': ';
304
			}
305
306
			// is this a start date?
307 1
			if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) &&
308 1
				( $date_value == $this->m_tlstart ) ) {
309
				// FIXME: Timeline scripts should support XSD format explicitly. They
310
				// currently seem to implement iso8601 which deviates from XSD in cases.
311
				// NOTE: We can assume $object to be an SMWDataValue in this case.
312 1
				$curmeta .= Html::element(
313 1
					'span',
314 1
					[ 'class' => 'smwtlstart' ],
315 1
					$object->getXMLSchemaDate()
316
				);
317 1
				$positions[$object->getHash()] = $object->getXMLSchemaDate();
318 1
				$hastime = true;
319
			}
320
321
			// is this the end date?
322 1
			if ( ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) &&
323 1
				( $date_value == $this->m_tlend ) ) {
324
				// NOTE: We can assume $object to be an SMWDataValue in this case.
325
				$curmeta .= Html::element(
326
					'span',
327
					[ 'class' => 'smwtlend' ],
328
					$object->getXMLSchemaDate( false )
329
				);
330
			}
331
332
			// find title for displaying event
333 1
			if ( !$hastitle ) {
334 1
				$curmeta .= Html::rawElement(
335 1
					'span',
336
					[
337 1
						'class' => $urlobject ? 'smwtlurl' : 'smwtltitle'
338
					],
339 1
					$objectlabel
340
				);
341
342 1
				if ( $pr->getMode() == SMWPrintRequest::PRINT_THIS ) {
343 1
					$curarticle = $object->getLongText( $outputmode, $l );
344 1
					$cururl = $object->getDataItem()->getTitle()->getFullUrl();
345
				}
346
347
				// NOTE: type Title of $object implied
348 1
				$hastitle = true;
349
			}
350
		} elseif ( $output ) {
351
			// it *can* happen that output is false here, if the subject was not printed (fixed subject query) and mutliple items appear in the first row
352
			$curdata .= ', ';
353
		}
354
355 1
		if ( !$first_col || !$first_value || $isEventline ) {
356 1
			$curdata .= $header . $objectlabel;
357 1
			$output = true;
358
		}
359
360 1
		if ( $isEventline && ( $pr->getMode() == SMWPrintRequest::PRINT_PROP ) && ( $pr->getTypeID(
361 1
				) == '_dat' ) && ( '' != $pr->getLabel(
362 1
				) ) && ( $date_value != $this->m_tlstart ) && ( $date_value != $this->m_tlend ) ) {
363
			$event = [
364
				$object->getXMLSchemaDate(),
365
				$pr->getLabel(),
366
				$object->getDataItem()->getSortKey(),
367
			];
368
		}
369
370 1
		return $event;
371
	}
372
373
	/**
374
	 * @see SMWResultPrinter::getParamDefinitions
375
	 *
376
	 * @since 1.8
377
	 *
378
	 * @param $definitions array of IParamDefinition
379
	 *
380
	 * @return array of IParamDefinition|array
381
	 */
382 1
	public function getParamDefinitions( array $definitions ) {
383 1
		$params = parent::getParamDefinitions( $definitions );
384
385 1
		$params['timelinesize'] = [
386
			'default' => '300px',
387
			'message' => 'srf_paramdesc_timelinesize',
388
		];
389
390 1
		$params['timelineposition'] = [
391
			'default' => 'middle',
392
			'message' => 'srf_paramdesc_timelineposition',
393
			'values' => [ 'start', 'middle', 'end', 'today' ],
394
		];
395
396 1
		$params['timelinestart'] = [
397
			'default' => '',
398
			'message' => 'srf_paramdesc_timelinestart',
399
		];
400
401 1
		$params['timelineend'] = [
402
			'default' => '',
403
			'message' => 'srf_paramdesc_timelineend',
404
		];
405
406 1
		$params['timelinebands'] = [
407
			'islist' => true,
408
			'default' => [ 'MONTH', 'YEAR' ],
409
			'message' => 'srf_paramdesc_timelinebands',
410
			'values' => [ 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH', 'YEAR', 'DECADE' ],
411
		];
412
413 1
		$params['template'] = [
414
			'message' => 'smw-paramdesc-template',
415
			'default' => '',
416
		];
417
418 1
		$params['named args'] = [
419
			'type' => 'boolean',
420
			'message' => 'smw-paramdesc-named_args',
421
			'default' => false,
422
		];
423
424 1
		return $params;
425
	}
426
427
}
428