Issues (4122)

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.

includes/media/ImageHandler.php (6 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
 * Media-handling base classes and generic functionality.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 * @ingroup Media
22
 */
23
24
/**
25
 * Media handler abstract base class for images
26
 *
27
 * @ingroup Media
28
 */
29
abstract class ImageHandler extends MediaHandler {
30
	/**
31
	 * @param File $file
32
	 * @return bool
33
	 */
34
	public function canRender( $file ) {
35
		return ( $file->getWidth() && $file->getHeight() );
36
	}
37
38
	public function getParamMap() {
39
		return [ 'img_width' => 'width' ];
40
	}
41
42
	public function validateParam( $name, $value ) {
43 View Code Duplication
		if ( in_array( $name, [ 'width', 'height' ] ) ) {
44
			if ( $value <= 0 ) {
45
				return false;
46
			} else {
47
				return true;
48
			}
49
		} else {
50
			return false;
51
		}
52
	}
53
54
	public function makeParamString( $params ) {
55
		if ( isset( $params['physicalWidth'] ) ) {
56
			$width = $params['physicalWidth'];
57
		} elseif ( isset( $params['width'] ) ) {
58
			$width = $params['width'];
59
		} else {
60
			throw new MediaTransformInvalidParametersException( 'No width specified to ' . __METHOD__ );
61
		}
62
63
		# Removed for ProofreadPage
64
		# $width = intval( $width );
65
		return "{$width}px";
66
	}
67
68 View Code Duplication
	public function parseParamString( $str ) {
69
		$m = false;
70
		if ( preg_match( '/^(\d+)px$/', $str, $m ) ) {
71
			return [ 'width' => $m[1] ];
72
		} else {
73
			return false;
74
		}
75
	}
76
77
	function getScriptParams( $params ) {
78
		return [ 'width' => $params['width'] ];
79
	}
80
81
	/**
82
	 * @param File $image
83
	 * @param array $params
84
	 * @return bool
85
	 */
86
	function normaliseParams( $image, &$params ) {
87
		$mimeType = $image->getMimeType();
88
89
		if ( !isset( $params['width'] ) ) {
90
			return false;
91
		}
92
93
		if ( !isset( $params['page'] ) ) {
94
			$params['page'] = 1;
95
		} else {
96
			$params['page'] = intval( $params['page'] );
97
			if ( $params['page'] > $image->pageCount() ) {
98
				$params['page'] = $image->pageCount();
99
			}
100
101
			if ( $params['page'] < 1 ) {
102
				$params['page'] = 1;
103
			}
104
		}
105
106
		$srcWidth = $image->getWidth( $params['page'] );
107
		$srcHeight = $image->getHeight( $params['page'] );
108
109
		if ( isset( $params['height'] ) && $params['height'] != -1 ) {
110
			# Height & width were both set
111
			if ( $params['width'] * $srcHeight > $params['height'] * $srcWidth ) {
112
				# Height is the relative smaller dimension, so scale width accordingly
113
				$params['width'] = self::fitBoxWidth( $srcWidth, $srcHeight, $params['height'] );
0 ignored issues
show
It seems like $srcWidth defined by $image->getWidth($params['page']) on line 106 can also be of type boolean; however, MediaHandler::fitBoxWidth() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
It seems like $srcHeight defined by $image->getHeight($params['page']) on line 107 can also be of type boolean; however, MediaHandler::fitBoxWidth() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
114
115
				if ( $params['width'] == 0 ) {
116
					# Very small image, so we need to rely on client side scaling :(
117
					$params['width'] = 1;
118
				}
119
120
				$params['physicalWidth'] = $params['width'];
121
			} else {
122
				# Height was crap, unset it so that it will be calculated later
123
				unset( $params['height'] );
124
			}
125
		}
126
127
		if ( !isset( $params['physicalWidth'] ) ) {
128
			# Passed all validations, so set the physicalWidth
129
			$params['physicalWidth'] = $params['width'];
130
		}
131
132
		# Because thumbs are only referred to by width, the height always needs
133
		# to be scaled by the width to keep the thumbnail sizes consistent,
134
		# even if it was set inside the if block above
135
		$params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
0 ignored issues
show
It seems like $srcWidth defined by $image->getWidth($params['page']) on line 106 can also be of type boolean; however, File::scaleHeight() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
It seems like $srcHeight defined by $image->getHeight($params['page']) on line 107 can also be of type boolean; however, File::scaleHeight() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
136
			$params['physicalWidth'] );
137
138
		# Set the height if it was not validated in the if block higher up
139
		if ( !isset( $params['height'] ) || $params['height'] == -1 ) {
140
			$params['height'] = $params['physicalHeight'];
141
		}
142
143
		if ( !$this->validateThumbParams( $params['physicalWidth'],
144
			$params['physicalHeight'], $srcWidth, $srcHeight, $mimeType )
0 ignored issues
show
It seems like $srcWidth defined by $image->getWidth($params['page']) on line 106 can also be of type boolean; however, ImageHandler::validateThumbParams() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
It seems like $srcHeight defined by $image->getHeight($params['page']) on line 107 can also be of type boolean; however, ImageHandler::validateThumbParams() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
145
		) {
146
			return false;
147
		}
148
149
		return true;
150
	}
151
152
	/**
153
	 * Validate thumbnail parameters and fill in the correct height
154
	 *
155
	 * @param int $width Specified width (input/output)
156
	 * @param int $height Height (output only)
157
	 * @param int $srcWidth Width of the source image
158
	 * @param int $srcHeight Height of the source image
159
	 * @param string $mimeType Unused
160
	 * @return bool False to indicate that an error should be returned to the user.
161
	 */
162
	function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
163
		$width = intval( $width );
164
165
		# Sanity check $width
166
		if ( $width <= 0 ) {
167
			wfDebug( __METHOD__ . ": Invalid destination width: $width\n" );
168
169
			return false;
170
		}
171
		if ( $srcWidth <= 0 ) {
172
			wfDebug( __METHOD__ . ": Invalid source width: $srcWidth\n" );
173
174
			return false;
175
		}
176
177
		$height = File::scaleHeight( $srcWidth, $srcHeight, $width );
178
		if ( $height == 0 ) {
179
			# Force height to be at least 1 pixel
180
			$height = 1;
181
		}
182
183
		return true;
184
	}
185
186
	/**
187
	 * @param File $image
188
	 * @param string $script
189
	 * @param array $params
190
	 * @return bool|MediaTransformOutput
191
	 */
192
	function getScriptedTransform( $image, $script, $params ) {
193
		if ( !$this->normaliseParams( $image, $params ) ) {
194
			return false;
195
		}
196
		$url = wfAppendQuery( $script, $this->getScriptParams( $params ) );
197
198
		if ( $image->mustRender() || $params['width'] < $image->getWidth() ) {
199
			return new ThumbnailImage( $image, $url, false, $params );
200
		}
201
	}
202
203
	function getImageSize( $image, $path ) {
204
		MediaWiki\suppressWarnings();
205
		$gis = getimagesize( $path );
206
		MediaWiki\restoreWarnings();
207
208
		return $gis;
209
	}
210
211
	/**
212
	 * Function that returns the number of pixels to be thumbnailed.
213
	 * Intended for animated GIFs to multiply by the number of frames.
214
	 *
215
	 * If the file doesn't support a notion of "area" return 0.
216
	 *
217
	 * @param File $image
218
	 * @return int
219
	 */
220
	function getImageArea( $image ) {
221
		return $image->getWidth() * $image->getHeight();
222
	}
223
224
	/**
225
	 * @param File $file
226
	 * @return string
227
	 */
228
	function getShortDesc( $file ) {
229
		global $wgLang;
230
		$nbytes = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
231
		$widthheight = wfMessage( 'widthheight' )
232
			->numParams( $file->getWidth(), $file->getHeight() )->escaped();
233
234
		return "$widthheight ($nbytes)";
235
	}
236
237
	/**
238
	 * @param File $file
239
	 * @return string
240
	 */
241
	function getLongDesc( $file ) {
242
		global $wgLang;
243
		$pages = $file->pageCount();
244
		$size = htmlspecialchars( $wgLang->formatSize( $file->getSize() ) );
245
		if ( $pages === false || $pages <= 1 ) {
246
			$msg = wfMessage( 'file-info-size' )->numParams( $file->getWidth(),
247
				$file->getHeight() )->params( $size,
248
					'<span class="mime-type">' . $file->getMimeType() . '</span>' )->parse();
249
		} else {
250
			$msg = wfMessage( 'file-info-size-pages' )->numParams( $file->getWidth(),
251
				$file->getHeight() )->params( $size,
252
					'<span class="mime-type">' . $file->getMimeType() . '</span>' )->numParams( $pages )->parse();
253
		}
254
255
		return $msg;
256
	}
257
258
	/**
259
	 * @param File $file
260
	 * @return string
261
	 */
262
	function getDimensionsString( $file ) {
263
		$pages = $file->pageCount();
264
		if ( $pages > 1 ) {
265
			return wfMessage( 'widthheightpage' )
266
				->numParams( $file->getWidth(), $file->getHeight(), $pages )->text();
267
		} else {
268
			return wfMessage( 'widthheight' )
269
				->numParams( $file->getWidth(), $file->getHeight() )->text();
270
		}
271
	}
272
273
	public function sanitizeParamsForBucketing( $params ) {
274
		$params = parent::sanitizeParamsForBucketing( $params );
275
276
		// We unset the height parameters in order to let normaliseParams recalculate them
277
		// Otherwise there might be a height discrepancy
278
		if ( isset( $params['height'] ) ) {
279
			unset( $params['height'] );
280
		}
281
282
		if ( isset( $params['physicalHeight'] ) ) {
283
			unset( $params['physicalHeight'] );
284
		}
285
286
		return $params;
287
	}
288
}
289