This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||||||
2 | ////////////////////////////////////////////////////////////// |
||||||||
3 | // phpThumb() by James Heinrich <[email protected]> // |
||||||||
4 | // available at http://phpthumb.sourceforge.net // |
||||||||
5 | // and/or https://github.com/JamesHeinrich/phpThumb // |
||||||||
6 | ////////////////////////////////////////////////////////////// |
||||||||
7 | /// // |
||||||||
8 | // See: phpthumb.readme.txt for usage instructions // |
||||||||
9 | // /// |
||||||||
10 | ////////////////////////////////////////////////////////////// |
||||||||
11 | |||||||||
12 | ob_start(); |
||||||||
13 | if (!require_once __DIR__ . '/phpthumb.functions.php') { |
||||||||
14 | ob_end_flush(); |
||||||||
15 | exit('failed to include_once("' . __DIR__ . '/phpthumb.functions.php")'); |
||||||||
16 | } |
||||||||
17 | ob_end_clean(); |
||||||||
18 | |||||||||
19 | /** |
||||||||
20 | * Class phpthumb |
||||||||
21 | */ |
||||||||
22 | class phpthumb |
||||||||
23 | { |
||||||||
24 | // public: |
||||||||
25 | // START PARAMETERS (for object mode and phpThumb.php) |
||||||||
26 | // See phpthumb.readme.txt for descriptions of what each of these values are |
||||||||
27 | public $src = null; // SouRCe filename |
||||||||
28 | public $new = null; // NEW image (phpThumb.php only) |
||||||||
29 | public $w = null; // Width |
||||||||
30 | public $h = null; // Height |
||||||||
31 | public $wp = null; // Width (Portrait Images Only) |
||||||||
32 | public $hp = null; // Height (Portrait Images Only) |
||||||||
33 | public $wl = null; // Width (Landscape Images Only) |
||||||||
34 | public $hl = null; // Height (Landscape Images Only) |
||||||||
35 | public $ws = null; // Width (Square Images Only) |
||||||||
36 | public $hs = null; // Height (Square Images Only) |
||||||||
37 | public $f = null; // output image Format |
||||||||
38 | public $q = 75; // jpeg output Quality |
||||||||
39 | public $sx = null; // Source crop top-left X position |
||||||||
40 | public $sy = null; // Source crop top-left Y position |
||||||||
41 | public $sw = null; // Source crop Width |
||||||||
42 | public $sh = null; // Source crop Height |
||||||||
43 | public $zc = null; // Zoom Crop |
||||||||
44 | public $bc = null; // Border Color |
||||||||
45 | public $bg = null; // BackGround color |
||||||||
46 | public $fltr = []; // FiLTeRs |
||||||||
47 | public $goto = null; // GO TO url after processing |
||||||||
48 | public $err = null; // default ERRor image filename |
||||||||
49 | public $xto = null; // extract eXif Thumbnail Only |
||||||||
50 | public $ra = null; // Rotate by Angle |
||||||||
51 | public $ar = null; // Auto Rotate |
||||||||
52 | public $aoe = null; // Allow Output Enlargement |
||||||||
53 | public $far = null; // Fixed Aspect Ratio |
||||||||
54 | public $iar = null; // Ignore Aspect Ratio |
||||||||
55 | public $maxb = null; // MAXimum Bytes |
||||||||
56 | public $down = null; // DOWNload thumbnail filename |
||||||||
57 | public $md5s = null; // MD5 hash of Source image |
||||||||
58 | public $sfn = 0; // Source Frame Number |
||||||||
59 | public $dpi = 150; // Dots Per Inch for vector source formats |
||||||||
60 | public $sia = null; // Save Image As filename |
||||||||
61 | public $file = null; // >>>deprecated, DO NOT USE, will be removed in future versions<<< |
||||||||
62 | public $phpThumbDebug = null; |
||||||||
63 | // END PARAMETERS |
||||||||
64 | |||||||||
65 | // public: |
||||||||
66 | // START CONFIGURATION OPTIONS (for object mode only) |
||||||||
67 | // See phpThumb.config.php for descriptions of what each of these settings do |
||||||||
68 | |||||||||
69 | // * Directory Configuration |
||||||||
70 | public $config_cache_directory = null; |
||||||||
71 | public $config_cache_directory_depth = 0; |
||||||||
72 | public $config_cache_disable_warning = true; |
||||||||
73 | public $config_cache_source_enabled = false; |
||||||||
74 | public $config_cache_source_directory = null; |
||||||||
75 | public $config_temp_directory = null; |
||||||||
76 | public $config_document_root = null; |
||||||||
77 | // * Default output configuration: |
||||||||
78 | public $config_output_format = 'jpeg'; |
||||||||
79 | public $config_output_maxwidth = 0; |
||||||||
80 | public $config_output_maxheight = 0; |
||||||||
81 | public $config_output_interlace = true; |
||||||||
82 | // * Error message configuration |
||||||||
83 | public $config_error_image_width = 400; |
||||||||
84 | public $config_error_image_height = 100; |
||||||||
85 | public $config_error_message_image_default = ''; |
||||||||
86 | public $config_error_bgcolor = 'CCCCFF'; |
||||||||
87 | public $config_error_textcolor = 'FF0000'; |
||||||||
88 | public $config_error_fontsize = 1; |
||||||||
89 | public $config_error_die_on_error = false; |
||||||||
90 | public $config_error_silent_die_on_error = false; |
||||||||
91 | public $config_error_die_on_source_failure = true; |
||||||||
92 | // * Anti-Hotlink Configuration: |
||||||||
93 | public $config_nohotlink_enabled = true; |
||||||||
94 | public $config_nohotlink_valid_domains = []; |
||||||||
95 | public $config_nohotlink_erase_image = true; |
||||||||
96 | public $config_nohotlink_text_message = 'Off-server thumbnailing is not allowed'; |
||||||||
97 | // * Off-server Linking Configuration: |
||||||||
98 | public $config_nooffsitelink_enabled = false; |
||||||||
99 | public $config_nooffsitelink_valid_domains = []; |
||||||||
100 | public $config_nooffsitelink_require_refer = false; |
||||||||
101 | public $config_nooffsitelink_erase_image = true; |
||||||||
102 | public $config_nooffsitelink_watermark_src = ''; |
||||||||
103 | public $config_nooffsitelink_text_message = 'Off-server linking is not allowed'; |
||||||||
104 | // * Border & Background default colors |
||||||||
105 | public $config_border_hexcolor = '000000'; |
||||||||
106 | public $config_background_hexcolor = 'FFFFFF'; |
||||||||
107 | // * TrueType Fonts |
||||||||
108 | public $config_ttf_directory = './fonts'; |
||||||||
109 | public $config_max_source_pixels = null; |
||||||||
110 | public $config_use_exif_thumbnail_for_speed = false; |
||||||||
111 | public $allow_local_http_src = false; |
||||||||
112 | public $config_imagemagick_path = null; |
||||||||
113 | public $config_prefer_imagemagick = true; |
||||||||
114 | public $config_imagemagick_use_thumbnail = true; |
||||||||
115 | public $config_cache_maxage = null; |
||||||||
116 | public $config_cache_maxsize = null; |
||||||||
117 | public $config_cache_maxfiles = null; |
||||||||
118 | public $config_cache_source_filemtime_ignore_local = false; |
||||||||
119 | public $config_cache_source_filemtime_ignore_remote = true; |
||||||||
120 | public $config_cache_default_only_suffix = false; |
||||||||
121 | public $config_cache_force_passthru = true; |
||||||||
122 | public $config_cache_prefix = ''; // default value set in the constructor below |
||||||||
123 | // * MySQL |
||||||||
124 | public $config_mysql_extension = null; |
||||||||
125 | public $config_mysql_query = null; |
||||||||
126 | public $config_mysql_hostname = null; |
||||||||
127 | public $config_mysql_username = null; |
||||||||
128 | public $config_mysql_password = null; |
||||||||
129 | public $config_mysql_database = null; |
||||||||
130 | // * Security |
||||||||
131 | public $config_high_security_enabled = true; |
||||||||
132 | public $config_high_security_password = null; |
||||||||
133 | public $config_high_security_url_separator = '&'; |
||||||||
134 | public $config_disable_debug = true; |
||||||||
135 | public $config_allow_src_above_docroot = false; |
||||||||
136 | public $config_allow_src_above_phpthumb = true; |
||||||||
137 | public $config_auto_allow_symlinks = true; // allow symlink target directories without explicitly whitelisting them |
||||||||
138 | public $config_additional_allowed_dirs = []; // additional directories to allow source images to be read from |
||||||||
139 | // * HTTP fopen |
||||||||
140 | public $config_http_fopen_timeout = 10; |
||||||||
141 | public $config_http_follow_redirect = true; |
||||||||
142 | // * Compatability |
||||||||
143 | public $config_disable_pathinfo_parsing = false; |
||||||||
144 | public $config_disable_imagecopyresampled = false; |
||||||||
145 | public $config_disable_onlycreateable_passthru = false; |
||||||||
146 | public $config_disable_realpath = false; |
||||||||
147 | public $config_http_user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7'; |
||||||||
148 | // END CONFIGURATION OPTIONS |
||||||||
149 | |||||||||
150 | // public: error messages (read-only; persistant) |
||||||||
151 | public $debugmessages = []; |
||||||||
152 | public $debugtiming = []; |
||||||||
153 | public $fatalerror = null; |
||||||||
154 | // private: (should not be modified directly) |
||||||||
155 | public $thumbnailQuality = 75; |
||||||||
156 | public $thumbnailFormat = null; |
||||||||
157 | public $sourceFilename = null; |
||||||||
158 | public $rawImageData = null; |
||||||||
159 | public $IMresizedData = null; |
||||||||
160 | public $outputImageData = null; |
||||||||
161 | public $useRawIMoutput = false; |
||||||||
162 | public $gdimg_output = null; |
||||||||
163 | public $gdimg_source = null; |
||||||||
164 | public $getimagesizeinfo = null; |
||||||||
165 | public $source_width = null; |
||||||||
166 | public $source_height = null; |
||||||||
167 | public $thumbnailCropX = null; |
||||||||
168 | public $thumbnailCropY = null; |
||||||||
169 | public $thumbnailCropW = null; |
||||||||
170 | public $thumbnailCropH = null; |
||||||||
171 | public $exif_thumbnail_width = null; |
||||||||
172 | public $exif_thumbnail_height = null; |
||||||||
173 | public $exif_thumbnail_type = null; |
||||||||
174 | public $exif_thumbnail_data = null; |
||||||||
175 | public $exif_raw_data = null; |
||||||||
176 | public $thumbnail_width = null; |
||||||||
177 | public $thumbnail_height = null; |
||||||||
178 | public $thumbnail_image_width = null; |
||||||||
179 | public $thumbnail_image_height = null; |
||||||||
180 | public $tempFilesToDelete = []; |
||||||||
181 | public $cache_filename = null; |
||||||||
182 | public $AlphaCapableFormats = ['png', 'ico', 'gif']; |
||||||||
183 | public $is_alpha = false; |
||||||||
184 | public $iswindows = null; |
||||||||
185 | public $issafemode = null; |
||||||||
186 | public $php_memory_limit = null; |
||||||||
187 | public $phpthumb_version = '1.7.14-201607141354'; |
||||||||
188 | ////////////////////////////////////////////////////////////////////// |
||||||||
189 | |||||||||
190 | // public: constructor |
||||||||
191 | public function __construct() |
||||||||
192 | { |
||||||||
193 | $this->phpThumb(); |
||||||||
194 | } |
||||||||
195 | |||||||||
196 | public function phpThumb() |
||||||||
197 | { |
||||||||
198 | $this->DebugTimingMessage('phpThumb() constructor', __FILE__, __LINE__); |
||||||||
199 | $this->DebugMessage('phpThumb() v' . $this->phpthumb_version, __FILE__, __LINE__); |
||||||||
200 | |||||||||
201 | foreach ([ini_get('memory_limit'), get_cfg_var('memory_limit')] as $php_config_memory_limit) { |
||||||||
202 | if (mb_strlen($php_config_memory_limit)) { |
||||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||||
203 | if ('G' === mb_substr($php_config_memory_limit, -1, 1)) { // PHP memory limit expressed in Gigabytes |
||||||||
0 ignored issues
–
show
It seems like
$php_config_memory_limit can also be of type array ; however, parameter $string of mb_substr() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
204 | $php_config_memory_limit = (int)mb_substr($php_config_memory_limit, 0, -1) * 1073741824; |
||||||||
205 | } elseif ('M' === mb_substr($php_config_memory_limit, -1, 1)) { // PHP memory limit expressed in Megabytes |
||||||||
206 | $php_config_memory_limit = (int)mb_substr($php_config_memory_limit, 0, -1) * 1048576; |
||||||||
207 | } |
||||||||
208 | $this->php_memory_limit = max($this->php_memory_limit, $php_config_memory_limit); |
||||||||
209 | } |
||||||||
210 | } |
||||||||
211 | if ($this->php_memory_limit > 0) { // could be "-1" for "no limit" |
||||||||
212 | $this->config_max_source_pixels = round($this->php_memory_limit * 0.20); // 20% of memory_limit |
||||||||
213 | } |
||||||||
214 | |||||||||
215 | $this->iswindows = ('WIN' === mb_strtoupper(mb_substr(PHP_OS, 0, 3))); |
||||||||
216 | $this->issafemode = (bool)preg_match('#(1|ON)#i', ini_get('safe_mode')); |
||||||||
217 | $this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : $this->config_document_root); |
||||||||
218 | $this->config_cache_prefix = (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] . '_' : ''); |
||||||||
219 | |||||||||
220 | $this->purgeTempFiles(); // purge existing temp files if re-initializing object |
||||||||
221 | |||||||||
222 | $php_sapi_name = mb_strtolower(function_exists('php_sapi_name') ? php_sapi_name() : ''); |
||||||||
223 | if ('cli' === $php_sapi_name) { |
||||||||
224 | $this->config_allow_src_above_docroot = true; |
||||||||
225 | } |
||||||||
226 | |||||||||
227 | if (!$this->config_disable_debug) { |
||||||||
228 | // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated |
||||||||
229 | $this->phpThumbDebug = (null === $this->phpThumbDebug ? 9 : max(1, (int)$this->phpThumbDebug)); |
||||||||
230 | } |
||||||||
231 | } |
||||||||
232 | |||||||||
233 | public function __destruct() |
||||||||
234 | { |
||||||||
235 | $this->purgeTempFiles(); |
||||||||
236 | } |
||||||||
237 | |||||||||
238 | // public: |
||||||||
239 | |||||||||
240 | /** |
||||||||
241 | * @return bool |
||||||||
242 | */ |
||||||||
243 | public function purgeTempFiles() |
||||||||
244 | { |
||||||||
245 | foreach ($this->tempFilesToDelete as $tempFileToDelete) { |
||||||||
246 | if (file_exists($tempFileToDelete)) { |
||||||||
247 | $this->DebugMessage('Deleting temp file "' . $tempFileToDelete . '"', __FILE__, __LINE__); |
||||||||
248 | @unlink($tempFileToDelete); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
249 | } |
||||||||
250 | } |
||||||||
251 | $this->tempFilesToDelete = []; |
||||||||
252 | |||||||||
253 | return true; |
||||||||
254 | } |
||||||||
255 | |||||||||
256 | // public: |
||||||||
257 | |||||||||
258 | /** |
||||||||
259 | * @param $sourceFilename |
||||||||
260 | * @return bool |
||||||||
261 | */ |
||||||||
262 | public function setSourceFilename($sourceFilename) |
||||||||
263 | { |
||||||||
264 | //$this->resetObject(); |
||||||||
265 | //$this->rawImageData = null; |
||||||||
266 | $this->sourceFilename = $sourceFilename; |
||||||||
267 | $this->src = $sourceFilename; |
||||||||
268 | if (null === $this->config_output_format) { |
||||||||
269 | $sourceFileExtension = mb_strtolower(mb_substr(mb_strrchr($sourceFilename, '.'), 1)); |
||||||||
270 | if (preg_match('#^[a-z]{3,4}$#', $sourceFileExtension)) { |
||||||||
271 | $this->config_output_format = $sourceFileExtension; |
||||||||
272 | $this->DebugMessage('setSourceFilename(' . $sourceFilename . ') set $this->config_output_format to "' . $sourceFileExtension . '"', __FILE__, __LINE__); |
||||||||
273 | } else { |
||||||||
274 | $this->DebugMessage('setSourceFilename(' . $sourceFilename . ') did NOT set $this->config_output_format to "' . $sourceFileExtension . '" because it did not seem like an appropriate image format', __FILE__, __LINE__); |
||||||||
275 | } |
||||||||
276 | } |
||||||||
277 | $this->DebugMessage('setSourceFilename(' . $sourceFilename . ') set $this->sourceFilename to "' . $this->sourceFilename . '"', __FILE__, __LINE__); |
||||||||
278 | |||||||||
279 | return true; |
||||||||
280 | } |
||||||||
281 | |||||||||
282 | // public: |
||||||||
283 | |||||||||
284 | /** |
||||||||
285 | * @param $rawImageData |
||||||||
286 | * @param string $sourceFilename |
||||||||
287 | * @return bool |
||||||||
288 | */ |
||||||||
289 | public function setSourceData($rawImageData, $sourceFilename = '') |
||||||||
290 | { |
||||||||
291 | //$this->resetObject(); |
||||||||
292 | //$this->sourceFilename = null; |
||||||||
293 | $this->rawImageData = $rawImageData; |
||||||||
294 | $this->DebugMessage('setSourceData() setting $this->rawImageData (' . mb_strlen($this->rawImageData) . ' bytes; magic="' . mb_substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(mb_substr($this->rawImageData, 0, 4)) . '))', __FILE__, __LINE__); |
||||||||
295 | if ($this->config_cache_source_enabled) { |
||||||||
296 | $sourceFilename = ($sourceFilename ?: md5($rawImageData)); |
||||||||
297 | if (!is_dir($this->config_cache_source_directory)) { |
||||||||
298 | $this->ErrorImage('$this->config_cache_source_directory (' . $this->config_cache_source_directory . ') is not a directory'); |
||||||||
299 | } elseif (!@is_writable($this->config_cache_source_directory)) { |
||||||||
300 | $this->ErrorImage('$this->config_cache_source_directory (' . $this->config_cache_source_directory . ') is not writable'); |
||||||||
301 | } |
||||||||
302 | $this->DebugMessage('setSourceData() attempting to save source image to "' . $this->config_cache_source_directory . DIRECTORY_SEPARATOR . urlencode($sourceFilename) . '"', __FILE__, __LINE__); |
||||||||
303 | if ($fp = @fopen($this->config_cache_source_directory . DIRECTORY_SEPARATOR . urlencode($sourceFilename), 'wb')) { |
||||||||
304 | fwrite($fp, $rawImageData); |
||||||||
305 | fclose($fp); |
||||||||
306 | } elseif (!$this->phpThumbDebug) { |
||||||||
307 | $this->ErrorImage('setSourceData() failed to write to source cache (' . $this->config_cache_source_directory . DIRECTORY_SEPARATOR . urlencode($sourceFilename) . ')'); |
||||||||
308 | } |
||||||||
309 | } |
||||||||
310 | |||||||||
311 | return true; |
||||||||
312 | } |
||||||||
313 | |||||||||
314 | // public: |
||||||||
315 | |||||||||
316 | /** |
||||||||
317 | * @param $gdimg |
||||||||
318 | * @return bool |
||||||||
319 | */ |
||||||||
320 | public function setSourceImageResource($gdimg) |
||||||||
321 | { |
||||||||
322 | //$this->resetObject(); |
||||||||
323 | $this->gdimg_source = $gdimg; |
||||||||
324 | |||||||||
325 | return true; |
||||||||
326 | } |
||||||||
327 | |||||||||
328 | // public: |
||||||||
329 | |||||||||
330 | /** |
||||||||
331 | * @param $param |
||||||||
332 | * @param $value |
||||||||
333 | * @return bool |
||||||||
334 | */ |
||||||||
335 | public function setParameter($param, $value) |
||||||||
336 | { |
||||||||
337 | if ('src' === $param) { |
||||||||
338 | $this->setSourceFilename($this->ResolveFilenameToAbsolute($value)); |
||||||||
339 | } elseif (@is_array($this->$param)) { |
||||||||
340 | if (is_array($value)) { |
||||||||
341 | foreach ($value as $arraykey => $arrayvalue) { |
||||||||
342 | array_push($this->$param, $arrayvalue); |
||||||||
343 | } |
||||||||
344 | } else { |
||||||||
345 | array_push($this->$param, $value); |
||||||||
346 | } |
||||||||
347 | } else { |
||||||||
348 | $this->$param = $value; |
||||||||
349 | } |
||||||||
350 | |||||||||
351 | return true; |
||||||||
352 | } |
||||||||
353 | |||||||||
354 | // public: |
||||||||
355 | |||||||||
356 | /** |
||||||||
357 | * @param $param |
||||||||
358 | * @return mixed |
||||||||
359 | */ |
||||||||
360 | public function getParameter($param) |
||||||||
361 | { |
||||||||
362 | //if (property_exists('phpThumb', $param)) { |
||||||||
363 | return $this->$param; |
||||||||
364 | //} |
||||||||
365 | //$this->DebugMessage('setParameter() attempting to get non-existant parameter "'.$param.'"', __FILE__, __LINE__); |
||||||||
366 | //return false; |
||||||||
367 | } |
||||||||
368 | |||||||||
369 | // public: |
||||||||
370 | |||||||||
371 | /** |
||||||||
372 | * @return bool |
||||||||
373 | */ |
||||||||
374 | public function GenerateThumbnail() |
||||||||
375 | { |
||||||||
376 | $this->setOutputFormat(); |
||||||||
377 | $this->phpThumbDebug('8a'); |
||||||||
378 | $this->ResolveSource(); |
||||||||
379 | $this->phpThumbDebug('8b'); |
||||||||
380 | $this->SetCacheFilename(); |
||||||||
381 | $this->phpThumbDebug('8c'); |
||||||||
382 | $this->ExtractEXIFgetImageSize(); |
||||||||
383 | $this->phpThumbDebug('8d'); |
||||||||
384 | if ($this->useRawIMoutput) { |
||||||||
385 | $this->DebugMessage('Skipping rest of GenerateThumbnail() because ($this->useRawIMoutput === true)', __FILE__, __LINE__); |
||||||||
386 | |||||||||
387 | return true; |
||||||||
388 | } |
||||||||
389 | $this->phpThumbDebug('8e'); |
||||||||
390 | if (!$this->SourceImageToGD()) { |
||||||||
391 | $this->DebugMessage('SourceImageToGD() failed', __FILE__, __LINE__); |
||||||||
392 | |||||||||
393 | return false; |
||||||||
394 | } |
||||||||
395 | $this->phpThumbDebug('8f'); |
||||||||
396 | $this->Rotate(); |
||||||||
397 | $this->phpThumbDebug('8g'); |
||||||||
398 | $this->CreateGDoutput(); |
||||||||
399 | $this->phpThumbDebug('8h'); |
||||||||
400 | |||||||||
401 | // default values, also applicable for far="C" |
||||||||
402 | $destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2); |
||||||||
403 | $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2); |
||||||||
404 | if (('L' === $this->far) || ('TL' === $this->far) || ('BL' === $this->far)) { |
||||||||
405 | $destination_offset_x = 0; |
||||||||
406 | } |
||||||||
407 | if (('R' === $this->far) || ('TR' === $this->far) || ('BR' === $this->far)) { |
||||||||
408 | $destination_offset_x = round($this->thumbnail_width - $this->thumbnail_image_width); |
||||||||
409 | } |
||||||||
410 | if (('T' === $this->far) || ('TL' === $this->far) || ('TR' === $this->far)) { |
||||||||
411 | $destination_offset_y = 0; |
||||||||
412 | } |
||||||||
413 | if (('B' === $this->far) || ('BL' === $this->far) || ('BR' === $this->far)) { |
||||||||
414 | $destination_offset_y = round($this->thumbnail_height - $this->thumbnail_image_height); |
||||||||
415 | } |
||||||||
416 | |||||||||
417 | // // copy/resize image to appropriate dimensions |
||||||||
418 | // $borderThickness = 0; |
||||||||
419 | // if (!empty($this->fltr)) { |
||||||||
420 | // foreach ($this->fltr as $key => $value) { |
||||||||
421 | // if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) { |
||||||||
422 | // $borderThickness = $matches[1]; |
||||||||
423 | // break; |
||||||||
424 | // } |
||||||||
425 | // } |
||||||||
426 | // } |
||||||||
427 | // if ($borderThickness > 0) { |
||||||||
428 | // //$this->DebugMessage('Skipping ImageResizeFunction() because BorderThickness="'.$borderThickness.'"', __FILE__, __LINE__); |
||||||||
429 | // $this->thumbnail_image_height /= 2; |
||||||||
430 | // } |
||||||||
431 | $this->ImageResizeFunction($this->gdimg_output, $this->gdimg_source, $destination_offset_x, $destination_offset_y, $this->thumbnailCropX, $this->thumbnailCropY, $this->thumbnail_image_width, $this->thumbnail_image_height, $this->thumbnailCropW, $this->thumbnailCropH); |
||||||||
432 | |||||||||
433 | $this->DebugMessage('memory_get_usage() after copy-resize = ' . (function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__); |
||||||||
434 | imagedestroy($this->gdimg_source); |
||||||||
435 | $this->DebugMessage('memory_get_usage() after imagedestroy = ' . (function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__); |
||||||||
436 | |||||||||
437 | $this->phpThumbDebug('8i'); |
||||||||
438 | $this->AntiOffsiteLinking(); |
||||||||
439 | $this->phpThumbDebug('8j'); |
||||||||
440 | $this->ApplyFilters(); |
||||||||
441 | $this->phpThumbDebug('8k'); |
||||||||
442 | $this->AlphaChannelFlatten(); |
||||||||
443 | $this->phpThumbDebug('8l'); |
||||||||
444 | $this->MaxFileSize(); |
||||||||
445 | $this->phpThumbDebug('8m'); |
||||||||
446 | |||||||||
447 | $this->DebugMessage('GenerateThumbnail() completed successfully', __FILE__, __LINE__); |
||||||||
448 | |||||||||
449 | return true; |
||||||||
450 | } |
||||||||
451 | |||||||||
452 | // public: |
||||||||
453 | |||||||||
454 | /** |
||||||||
455 | * @return bool |
||||||||
456 | */ |
||||||||
457 | public function RenderOutput() |
||||||||
458 | { |
||||||||
459 | if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) { |
||||||||
460 | $this->DebugMessage('RenderOutput() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__); |
||||||||
461 | |||||||||
462 | return false; |
||||||||
463 | } |
||||||||
464 | if (!$this->thumbnailFormat) { |
||||||||
465 | $this->DebugMessage('RenderOutput() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__); |
||||||||
466 | |||||||||
467 | return false; |
||||||||
468 | } |
||||||||
469 | if ($this->useRawIMoutput) { |
||||||||
470 | $this->DebugMessage('RenderOutput copying $this->IMresizedData (' . mb_strlen($this->IMresizedData) . ' bytes) to $this->outputImage', __FILE__, __LINE__); |
||||||||
471 | $this->outputImageData = $this->IMresizedData; |
||||||||
472 | |||||||||
473 | return true; |
||||||||
474 | } |
||||||||
475 | |||||||||
476 | $builtin_formats = []; |
||||||||
477 | if (function_exists('imagetypes')) { |
||||||||
478 | $imagetypes = imagetypes(); |
||||||||
479 | $builtin_formats['wbmp'] = (bool)($imagetypes & IMG_WBMP); |
||||||||
480 | $builtin_formats['jpg'] = (bool)($imagetypes & IMG_JPG); |
||||||||
481 | $builtin_formats['gif'] = (bool)($imagetypes & IMG_GIF); |
||||||||
482 | $builtin_formats['png'] = (bool)($imagetypes & IMG_PNG); |
||||||||
483 | } |
||||||||
484 | |||||||||
485 | $this->DebugMessage('imageinterlace($this->gdimg_output, ' . (int)$this->config_output_interlace . ')', __FILE__, __LINE__); |
||||||||
486 | imageinterlace($this->gdimg_output, (int)$this->config_output_interlace); |
||||||||
487 | |||||||||
488 | $this->DebugMessage('RenderOutput() attempting image' . mb_strtolower(@$this->thumbnailFormat) . '($this->gdimg_output)', __FILE__, __LINE__); |
||||||||
489 | ob_start(); |
||||||||
490 | switch ($this->thumbnailFormat) { |
||||||||
491 | case 'wbmp': |
||||||||
492 | if (empty($builtin_formats['wbmp'])) { |
||||||||
493 | $this->DebugMessage('GD does not have required built-in support for WBMP output', __FILE__, __LINE__); |
||||||||
494 | ob_end_clean(); |
||||||||
495 | |||||||||
496 | return false; |
||||||||
497 | } |
||||||||
498 | imagejpeg($this->gdimg_output, null, $this->thumbnailQuality); |
||||||||
499 | $this->outputImageData = ob_get_contents(); |
||||||||
500 | break; |
||||||||
501 | case 'jpeg': |
||||||||
502 | case 'jpg': // should be "jpeg" not "jpg" but just in case... |
||||||||
503 | if (empty($builtin_formats['jpg'])) { |
||||||||
504 | $this->DebugMessage('GD does not have required built-in support for JPEG output', __FILE__, __LINE__); |
||||||||
505 | ob_end_clean(); |
||||||||
506 | |||||||||
507 | return false; |
||||||||
508 | } |
||||||||
509 | imagejpeg($this->gdimg_output, null, $this->thumbnailQuality); |
||||||||
510 | $this->outputImageData = ob_get_contents(); |
||||||||
511 | break; |
||||||||
512 | case 'png': |
||||||||
513 | if (empty($builtin_formats['png'])) { |
||||||||
514 | $this->DebugMessage('GD does not have required built-in support for PNG output', __FILE__, __LINE__); |
||||||||
515 | ob_end_clean(); |
||||||||
516 | |||||||||
517 | return false; |
||||||||
518 | } |
||||||||
519 | if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.1.2', '>=')) { |
||||||||
520 | // https://github.com/JamesHeinrich/phpThumb/issues/24 |
||||||||
521 | |||||||||
522 | /* http://php.net/manual/en/function.imagepng.php: |
||||||||
523 | from php source (gd.h): |
||||||||
524 | 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all, |
||||||||
525 | :: 1 is FASTEST but produces larger files, 9 provides the best |
||||||||
526 | :: compression (smallest files) but takes a long time to compress, and |
||||||||
527 | :: -1 selects the default compiled into the zlib library. |
||||||||
528 | Conclusion: Based on the Zlib manual (http://www.zlib.net/manual.html) the default compression level is set to 6. |
||||||||
529 | */ |
||||||||
530 | if (($this->thumbnailQuality >= -1) && ($this->thumbnailQuality <= 9)) { |
||||||||
531 | $PNGquality = $this->thumbnailQuality; |
||||||||
532 | } else { |
||||||||
533 | $this->DebugMessage('Specified thumbnailQuality "' . $this->thumbnailQuality . '" is outside the accepted range (0-9, or -1). Using 6 as default value.', __FILE__, __LINE__); |
||||||||
534 | $PNGquality = 6; |
||||||||
535 | } |
||||||||
536 | imagepng($this->gdimg_output, null, $PNGquality); |
||||||||
537 | } else { |
||||||||
538 | imagepng($this->gdimg_output); |
||||||||
539 | } |
||||||||
540 | $this->outputImageData = ob_get_contents(); |
||||||||
541 | break; |
||||||||
542 | case 'gif': |
||||||||
543 | if (empty($builtin_formats['gif'])) { |
||||||||
544 | $this->DebugMessage('GD does not have required built-in support for GIF output', __FILE__, __LINE__); |
||||||||
545 | ob_end_clean(); |
||||||||
546 | |||||||||
547 | return false; |
||||||||
548 | } |
||||||||
549 | imagegif($this->gdimg_output); |
||||||||
550 | $this->outputImageData = ob_get_contents(); |
||||||||
551 | break; |
||||||||
552 | case 'bmp': |
||||||||
553 | if (!@require_once __DIR__ . '/phpthumb.bmp.php') { |
||||||||
554 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__); |
||||||||
555 | ob_end_clean(); |
||||||||
556 | |||||||||
557 | return false; |
||||||||
558 | } |
||||||||
559 | $phpthumb_bmp = new phpthumb_bmp(); |
||||||||
560 | $this->outputImageData = $phpthumb_bmp->GD2BMPstring($this->gdimg_output); |
||||||||
561 | unset($phpthumb_bmp); |
||||||||
562 | break; |
||||||||
563 | case 'ico': |
||||||||
564 | if (!@require_once __DIR__ . '/phpthumb.ico.php') { |
||||||||
565 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__); |
||||||||
566 | ob_end_clean(); |
||||||||
567 | |||||||||
568 | return false; |
||||||||
569 | } |
||||||||
570 | $phpthumb_ico = new phpthumb_ico(); |
||||||||
571 | $arrayOfOutputImages = [$this->gdimg_output]; |
||||||||
572 | $this->outputImageData = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages); |
||||||||
573 | unset($phpthumb_ico); |
||||||||
574 | break; |
||||||||
575 | default: |
||||||||
576 | $this->DebugMessage('RenderOutput failed because $this->thumbnailFormat "' . $this->thumbnailFormat . '" is not valid', __FILE__, __LINE__); |
||||||||
577 | ob_end_clean(); |
||||||||
578 | |||||||||
579 | return false; |
||||||||
580 | } |
||||||||
581 | ob_end_clean(); |
||||||||
582 | if (!$this->outputImageData) { |
||||||||
583 | $this->DebugMessage('RenderOutput() for "' . $this->thumbnailFormat . '" failed', __FILE__, __LINE__); |
||||||||
584 | ob_end_clean(); |
||||||||
585 | |||||||||
586 | return false; |
||||||||
587 | } |
||||||||
588 | $this->DebugMessage('RenderOutput() completing with $this->outputImageData = ' . mb_strlen($this->outputImageData) . ' bytes', __FILE__, __LINE__); |
||||||||
589 | |||||||||
590 | return true; |
||||||||
591 | } |
||||||||
592 | |||||||||
593 | // public: |
||||||||
594 | |||||||||
595 | /** |
||||||||
596 | * @param $filename |
||||||||
597 | * @return bool |
||||||||
598 | */ |
||||||||
599 | public function RenderToFile($filename) |
||||||||
600 | { |
||||||||
601 | if (preg_match('#^[a-z0-9]+://#i', $filename)) { |
||||||||
602 | $this->DebugMessage('RenderToFile() failed because $filename (' . $filename . ') is a URL', __FILE__, __LINE__); |
||||||||
603 | |||||||||
604 | return false; |
||||||||
605 | } |
||||||||
606 | // render thumbnail to this file only, do not cache, do not output to browser |
||||||||
607 | //$renderfilename = $this->ResolveFilenameToAbsolute(dirname($filename)).DIRECTORY_SEPARATOR.basename($filename); |
||||||||
608 | $renderfilename = $filename; |
||||||||
609 | if (('/' !== $filename[0]) && ('\\' !== $filename[0]) && (':' !== $filename[1])) { |
||||||||
610 | $renderfilename = $this->ResolveFilenameToAbsolute($renderfilename); |
||||||||
611 | } |
||||||||
612 | if (!@is_writable(dirname($renderfilename))) { |
||||||||
613 | $this->DebugMessage('RenderToFile() failed because "' . \dirname($renderfilename) . '/" is not writable', __FILE__, __LINE__); |
||||||||
614 | |||||||||
615 | return false; |
||||||||
616 | } |
||||||||
617 | if (@is_file($renderfilename) && !@is_writable($renderfilename)) { |
||||||||
618 | $this->DebugMessage('RenderToFile() failed because "' . $renderfilename . '" is not writable', __FILE__, __LINE__); |
||||||||
619 | |||||||||
620 | return false; |
||||||||
621 | } |
||||||||
622 | |||||||||
623 | if ($this->RenderOutput()) { |
||||||||
624 | if (file_put_contents($renderfilename, $this->outputImageData)) { |
||||||||
625 | $this->DebugMessage('RenderToFile(' . $renderfilename . ') succeeded', __FILE__, __LINE__); |
||||||||
626 | |||||||||
627 | return true; |
||||||||
628 | } |
||||||||
629 | if (!@file_exists($renderfilename)) { |
||||||||
630 | $this->DebugMessage('RenderOutput [' . $this->thumbnailFormat . '(' . $renderfilename . ')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__); |
||||||||
631 | } |
||||||||
632 | } else { |
||||||||
633 | $this->DebugMessage('RenderOutput [' . $this->thumbnailFormat . '(' . $renderfilename . ')] failed', __FILE__, __LINE__); |
||||||||
634 | } |
||||||||
635 | |||||||||
636 | return false; |
||||||||
637 | } |
||||||||
638 | |||||||||
639 | // public: |
||||||||
640 | |||||||||
641 | /** |
||||||||
642 | * @return bool |
||||||||
643 | */ |
||||||||
644 | public function OutputThumbnail() |
||||||||
645 | { |
||||||||
646 | $this->purgeTempFiles(); |
||||||||
647 | |||||||||
648 | if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) { |
||||||||
649 | $this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__); |
||||||||
650 | |||||||||
651 | return false; |
||||||||
652 | } |
||||||||
653 | if (headers_sent()) { |
||||||||
654 | return $this->ErrorImage('OutputThumbnail() failed - headers already sent'); |
||||||||
655 | } |
||||||||
656 | |||||||||
657 | $downloadfilename = phpthumb_functions::SanitizeFilename(is_string($this->sia) ? $this->sia : ($this->down ?: 'phpThumb_generated_thumbnail' . '.' . $this->thumbnailFormat)); |
||||||||
658 | $this->DebugMessage('Content-Disposition header filename set to "' . $downloadfilename . '"', __FILE__, __LINE__); |
||||||||
659 | if ($downloadfilename) { |
||||||||
660 | header('Content-Disposition: ' . ($this->down ? 'attachment' : 'inline') . '; filename="' . $downloadfilename . '"'); |
||||||||
661 | } else { |
||||||||
662 | $this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__); |
||||||||
663 | } |
||||||||
664 | |||||||||
665 | if ($this->useRawIMoutput) { |
||||||||
666 | header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat)); |
||||||||
0 ignored issues
–
show
Are you sure
phpthumb_functions::Imag...$this->thumbnailFormat) of type false|mixed|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
667 | echo $this->IMresizedData; |
||||||||
668 | } else { |
||||||||
669 | $this->DebugMessage('imageinterlace($this->gdimg_output, ' . (int)$this->config_output_interlace . ')', __FILE__, __LINE__); |
||||||||
670 | imageinterlace($this->gdimg_output, (int)$this->config_output_interlace); |
||||||||
671 | switch ($this->thumbnailFormat) { |
||||||||
672 | case 'jpeg': |
||||||||
673 | header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat)); |
||||||||
674 | $ImageOutFunction = 'image' . $this->thumbnailFormat; |
||||||||
675 | @$ImageOutFunction($this->gdimg_output, null, $this->thumbnailQuality); |
||||||||
676 | break; |
||||||||
677 | case 'png': |
||||||||
678 | case 'gif': |
||||||||
679 | header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat)); |
||||||||
680 | $ImageOutFunction = 'image' . $this->thumbnailFormat; |
||||||||
681 | @$ImageOutFunction($this->gdimg_output); |
||||||||
682 | break; |
||||||||
683 | case 'bmp': |
||||||||
684 | if (!@require_once __DIR__ . '/phpthumb.bmp.php') { |
||||||||
685 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__); |
||||||||
686 | |||||||||
687 | return false; |
||||||||
688 | } |
||||||||
689 | $phpthumb_bmp = new phpthumb_bmp(); |
||||||||
690 | if (is_object($phpthumb_bmp)) { |
||||||||
691 | $bmp_data = $phpthumb_bmp->GD2BMPstring($this->gdimg_output); |
||||||||
692 | unset($phpthumb_bmp); |
||||||||
693 | if (!$bmp_data) { |
||||||||
694 | $this->DebugMessage('$phpthumb_bmp->GD2BMPstring() failed', __FILE__, __LINE__); |
||||||||
695 | |||||||||
696 | return false; |
||||||||
697 | } |
||||||||
698 | header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat)); |
||||||||
699 | echo $bmp_data; |
||||||||
700 | } else { |
||||||||
701 | $this->DebugMessage('new phpthumb_bmp() failed', __FILE__, __LINE__); |
||||||||
702 | |||||||||
703 | return false; |
||||||||
704 | } |
||||||||
705 | break; |
||||||||
706 | case 'ico': |
||||||||
707 | if (!@require_once __DIR__ . '/phpthumb.ico.php') { |
||||||||
708 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__); |
||||||||
709 | |||||||||
710 | return false; |
||||||||
711 | } |
||||||||
712 | $phpthumb_ico = new phpthumb_ico(); |
||||||||
713 | if (is_object($phpthumb_ico)) { |
||||||||
714 | $arrayOfOutputImages = [$this->gdimg_output]; |
||||||||
715 | $ico_data = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages); |
||||||||
716 | unset($phpthumb_ico); |
||||||||
717 | if (!$ico_data) { |
||||||||
718 | $this->DebugMessage('$phpthumb_ico->GD2ICOstring() failed', __FILE__, __LINE__); |
||||||||
719 | |||||||||
720 | return false; |
||||||||
721 | } |
||||||||
722 | header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat)); |
||||||||
723 | echo $ico_data; |
||||||||
724 | } else { |
||||||||
725 | $this->DebugMessage('new phpthumb_ico() failed', __FILE__, __LINE__); |
||||||||
726 | |||||||||
727 | return false; |
||||||||
728 | } |
||||||||
729 | break; |
||||||||
730 | default: |
||||||||
731 | $this->DebugMessage('OutputThumbnail failed because $this->thumbnailFormat "' . $this->thumbnailFormat . '" is not valid', __FILE__, __LINE__); |
||||||||
732 | |||||||||
733 | return false; |
||||||||
734 | break; |
||||||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||||||
735 | } |
||||||||
736 | } |
||||||||
737 | |||||||||
738 | return true; |
||||||||
739 | } |
||||||||
740 | |||||||||
741 | // public: |
||||||||
742 | |||||||||
743 | /** |
||||||||
744 | * @return bool |
||||||||
745 | */ |
||||||||
746 | public function CleanUpCacheDirectory() |
||||||||
747 | { |
||||||||
748 | $this->DebugMessage( |
||||||||
749 | 'CleanUpCacheDirectory() set to purge (' . (null === $this->config_cache_maxage ? 'NULL' : number_format($this->config_cache_maxage / 86400, 1)) . ' days; ' . (null === $this->config_cache_maxsize ? 'NULL' : number_format($this->config_cache_maxsize / 1048576, 2)) . ' MB; ' . (null |
||||||||
750 | === $this->config_cache_maxfiles ? 'NULL' : number_format( |
||||||||
751 | $this->config_cache_maxfiles |
||||||||
752 | )) . ' files)', |
||||||||
753 | __FILE__, |
||||||||
754 | __LINE__ |
||||||||
755 | ); |
||||||||
756 | |||||||||
757 | if (!is_writable($this->config_cache_directory)) { |
||||||||
758 | $this->DebugMessage('CleanUpCacheDirectory() skipped because "' . $this->config_cache_directory . '" is not writable', __FILE__, __LINE__); |
||||||||
759 | |||||||||
760 | return true; |
||||||||
761 | } |
||||||||
762 | |||||||||
763 | // cache status of cache directory for 1 hour to avoid hammering the filesystem functions |
||||||||
764 | $phpThumbCacheStats_filename = $this->config_cache_directory . DIRECTORY_SEPARATOR . 'phpThumbCacheStats.txt'; |
||||||||
765 | if (file_exists($phpThumbCacheStats_filename) && is_readable($phpThumbCacheStats_filename) |
||||||||
766 | && (filemtime($phpThumbCacheStats_filename) >= (time() - 3600))) { |
||||||||
767 | $this->DebugMessage('CleanUpCacheDirectory() skipped because "' . $phpThumbCacheStats_filename . '" is recently modified', __FILE__, __LINE__); |
||||||||
768 | |||||||||
769 | return true; |
||||||||
770 | } |
||||||||
771 | if (!@touch($phpThumbCacheStats_filename)) { |
||||||||
772 | $this->DebugMessage('touch(' . $phpThumbCacheStats_filename . ') failed', __FILE__, __LINE__); |
||||||||
773 | } |
||||||||
774 | |||||||||
775 | $DeletedKeys = []; |
||||||||
776 | $AllFilesInCacheDirectory = []; |
||||||||
777 | if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) |
||||||||
778 | || ($this->config_cache_maxfiles > 0)) { |
||||||||
779 | $CacheDirOldFilesAge = []; |
||||||||
780 | $CacheDirOldFilesSize = []; |
||||||||
781 | $AllFilesInCacheDirectory = phpthumb_functions::GetAllFilesInSubfolders($this->config_cache_directory); |
||||||||
782 | foreach ($AllFilesInCacheDirectory as $fullfilename) { |
||||||||
783 | if (preg_match('#' . preg_quote($this->config_cache_prefix) . '#i', $fullfilename) |
||||||||
784 | && file_exists($fullfilename)) { |
||||||||
785 | $CacheDirOldFilesAge[$fullfilename] = @fileatime($fullfilename); |
||||||||
786 | if (0 == $CacheDirOldFilesAge[$fullfilename]) { |
||||||||
787 | $CacheDirOldFilesAge[$fullfilename] = @filemtime($fullfilename); |
||||||||
788 | } |
||||||||
789 | $CacheDirOldFilesSize[$fullfilename] = @filesize($fullfilename); |
||||||||
790 | } |
||||||||
791 | } |
||||||||
792 | if (empty($CacheDirOldFilesSize)) { |
||||||||
793 | $this->DebugMessage('CleanUpCacheDirectory() skipped because $CacheDirOldFilesSize is empty (phpthumb_functions::GetAllFilesInSubfolders(' . $this->config_cache_directory . ') found no files)', __FILE__, __LINE__); |
||||||||
794 | |||||||||
795 | return true; |
||||||||
796 | } |
||||||||
797 | $DeletedKeys['zerobyte'] = []; |
||||||||
798 | foreach ($CacheDirOldFilesSize as $fullfilename => $filesize) { |
||||||||
799 | // purge all zero-size files more than an hour old (to prevent trying to delete just-created and/or in-use files) |
||||||||
800 | $cutofftime = time() - 3600; |
||||||||
801 | if ((0 == $filesize) && ($CacheDirOldFilesAge[$fullfilename] < $cutofftime)) { |
||||||||
802 | $this->DebugMessage('deleting "' . $fullfilename . '"', __FILE__, __LINE__); |
||||||||
803 | if (@unlink($fullfilename)) { |
||||||||
804 | $DeletedKeys['zerobyte'][] = $fullfilename; |
||||||||
805 | unset($CacheDirOldFilesSize[$fullfilename]); |
||||||||
806 | unset($CacheDirOldFilesAge[$fullfilename]); |
||||||||
807 | } |
||||||||
808 | } |
||||||||
809 | } |
||||||||
810 | $this->DebugMessage('CleanUpCacheDirectory() purged ' . count($DeletedKeys['zerobyte']) . ' zero-byte files', __FILE__, __LINE__); |
||||||||
811 | asort($CacheDirOldFilesAge); |
||||||||
812 | |||||||||
813 | if ($this->config_cache_maxfiles > 0) { |
||||||||
814 | $TotalCachedFiles = count($CacheDirOldFilesAge); |
||||||||
815 | $DeletedKeys['maxfiles'] = []; |
||||||||
816 | foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) { |
||||||||
817 | if ($TotalCachedFiles > $this->config_cache_maxfiles) { |
||||||||
818 | $this->DebugMessage('deleting "' . $fullfilename . '"', __FILE__, __LINE__); |
||||||||
819 | if (@unlink($fullfilename)) { |
||||||||
820 | $TotalCachedFiles--; |
||||||||
821 | $DeletedKeys['maxfiles'][] = $fullfilename; |
||||||||
822 | } |
||||||||
823 | } else { |
||||||||
824 | // there are few enough files to keep the rest |
||||||||
825 | break; |
||||||||
826 | } |
||||||||
827 | } |
||||||||
828 | $this->DebugMessage('CleanUpCacheDirectory() purged ' . count($DeletedKeys['maxfiles']) . ' files based on (config_cache_maxfiles=' . $this->config_cache_maxfiles . ')', __FILE__, __LINE__); |
||||||||
829 | foreach ($DeletedKeys['maxfiles'] as $fullfilename) { |
||||||||
830 | unset($CacheDirOldFilesAge[$fullfilename]); |
||||||||
831 | unset($CacheDirOldFilesSize[$fullfilename]); |
||||||||
832 | } |
||||||||
833 | } |
||||||||
834 | |||||||||
835 | if ($this->config_cache_maxage > 0) { |
||||||||
836 | $mindate = time() - $this->config_cache_maxage; |
||||||||
837 | $DeletedKeys['maxage'] = []; |
||||||||
838 | foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) { |
||||||||
839 | if ($filedate > 0) { |
||||||||
840 | if ($filedate < $mindate) { |
||||||||
841 | $this->DebugMessage('deleting "' . $fullfilename . '"', __FILE__, __LINE__); |
||||||||
842 | if (@unlink($fullfilename)) { |
||||||||
843 | $DeletedKeys['maxage'][] = $fullfilename; |
||||||||
844 | } |
||||||||
845 | } else { |
||||||||
846 | // the rest of the files are new enough to keep |
||||||||
847 | break; |
||||||||
848 | } |
||||||||
849 | } |
||||||||
850 | } |
||||||||
851 | $this->DebugMessage('CleanUpCacheDirectory() purged ' . count($DeletedKeys['maxage']) . ' files based on (config_cache_maxage=' . $this->config_cache_maxage . ')', __FILE__, __LINE__); |
||||||||
852 | foreach ($DeletedKeys['maxage'] as $fullfilename) { |
||||||||
853 | unset($CacheDirOldFilesAge[$fullfilename]); |
||||||||
854 | unset($CacheDirOldFilesSize[$fullfilename]); |
||||||||
855 | } |
||||||||
856 | } |
||||||||
857 | |||||||||
858 | if ($this->config_cache_maxsize > 0) { |
||||||||
859 | $TotalCachedFileSize = array_sum($CacheDirOldFilesSize); |
||||||||
860 | $DeletedKeys['maxsize'] = []; |
||||||||
861 | foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) { |
||||||||
862 | if ($TotalCachedFileSize > $this->config_cache_maxsize) { |
||||||||
863 | $this->DebugMessage('deleting "' . $fullfilename . '"', __FILE__, __LINE__); |
||||||||
864 | if (@unlink($fullfilename)) { |
||||||||
865 | $TotalCachedFileSize -= $CacheDirOldFilesSize[$fullfilename]; |
||||||||
866 | $DeletedKeys['maxsize'][] = $fullfilename; |
||||||||
867 | } |
||||||||
868 | } else { |
||||||||
869 | // the total filesizes are small enough to keep the rest of the files |
||||||||
870 | break; |
||||||||
871 | } |
||||||||
872 | } |
||||||||
873 | $this->DebugMessage('CleanUpCacheDirectory() purged ' . count($DeletedKeys['maxsize']) . ' files based on (config_cache_maxsize=' . $this->config_cache_maxsize . ')', __FILE__, __LINE__); |
||||||||
874 | foreach ($DeletedKeys['maxsize'] as $fullfilename) { |
||||||||
875 | unset($CacheDirOldFilesAge[$fullfilename]); |
||||||||
876 | unset($CacheDirOldFilesSize[$fullfilename]); |
||||||||
877 | } |
||||||||
878 | } |
||||||||
879 | } else { |
||||||||
880 | $this->DebugMessage('skipping CleanUpCacheDirectory() because config set to not use it', __FILE__, __LINE__); |
||||||||
881 | } |
||||||||
882 | $totalpurged = 0; |
||||||||
883 | foreach ($DeletedKeys as $key => $value) { |
||||||||
884 | $totalpurged += count($value); |
||||||||
885 | } |
||||||||
886 | $this->DebugMessage('CleanUpCacheDirectory() purged ' . $totalpurged . ' files (from ' . count($AllFilesInCacheDirectory) . ') based on config settings', __FILE__, __LINE__); |
||||||||
887 | if ($totalpurged > 0) { |
||||||||
888 | $empty_dirs = []; |
||||||||
889 | foreach ($AllFilesInCacheDirectory as $fullfilename) { |
||||||||
890 | if (is_dir($fullfilename)) { |
||||||||
891 | $empty_dirs[$this->realPathSafe($fullfilename)] = 1; |
||||||||
892 | } else { |
||||||||
893 | unset($empty_dirs[$this->realPathSafe(dirname($fullfilename))]); |
||||||||
894 | } |
||||||||
895 | } |
||||||||
896 | krsort($empty_dirs); |
||||||||
897 | $totalpurgeddirs = 0; |
||||||||
898 | foreach ($empty_dirs as $empty_dir => $dummy) { |
||||||||
899 | if ($empty_dir == $this->config_cache_directory) { |
||||||||
900 | // shouldn't happen, but just in case, don't let it delete actual cache directory |
||||||||
901 | continue; |
||||||||
902 | } elseif (@rmdir($empty_dir)) { |
||||||||
903 | $totalpurgeddirs++; |
||||||||
904 | } else { |
||||||||
905 | $this->DebugMessage('failed to rmdir(' . $empty_dir . ')', __FILE__, __LINE__); |
||||||||
906 | } |
||||||||
907 | } |
||||||||
908 | $this->DebugMessage('purged ' . $totalpurgeddirs . ' empty directories', __FILE__, __LINE__); |
||||||||
909 | } |
||||||||
910 | |||||||||
911 | return true; |
||||||||
912 | } |
||||||||
913 | |||||||||
914 | ////////////////////////////////////////////////////////////////////// |
||||||||
915 | |||||||||
916 | // private: re-initializator (call between rendering multiple images with one object) |
||||||||
917 | |||||||||
918 | /** |
||||||||
919 | * @return bool |
||||||||
920 | */ |
||||||||
921 | public function resetObject() |
||||||||
922 | { |
||||||||
923 | $class_vars = get_class_vars(get_class($this)); |
||||||||
924 | foreach ($class_vars as $key => $value) { |
||||||||
925 | // do not clobber debug or config info |
||||||||
926 | if (!preg_match('#^(config_|debug|fatalerror)#i', $key)) { |
||||||||
927 | $this->$key = $value; |
||||||||
928 | } |
||||||||
929 | } |
||||||||
930 | $this->phpThumb(); // re-initialize some class variables |
||||||||
931 | |||||||||
932 | return true; |
||||||||
933 | } |
||||||||
934 | |||||||||
935 | ////////////////////////////////////////////////////////////////////// |
||||||||
936 | |||||||||
937 | /** |
||||||||
938 | * @return bool |
||||||||
939 | */ |
||||||||
940 | public function ResolveSource() |
||||||||
941 | { |
||||||||
942 | if (is_resource($this->gdimg_source)) { |
||||||||
943 | $this->DebugMessage('ResolveSource() exiting because is_resource($this->gdimg_source)', __FILE__, __LINE__); |
||||||||
944 | |||||||||
945 | return true; |
||||||||
946 | } |
||||||||
947 | if ($this->rawImageData) { |
||||||||
948 | $this->sourceFilename = null; |
||||||||
949 | $this->DebugMessage('ResolveSource() exiting because $this->rawImageData is set (' . number_format(mb_strlen($this->rawImageData)) . ' bytes)', __FILE__, __LINE__); |
||||||||
950 | |||||||||
951 | return true; |
||||||||
952 | } |
||||||||
953 | if ($this->sourceFilename) { |
||||||||
954 | $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->sourceFilename); |
||||||||
955 | $this->DebugMessage('$this->sourceFilename set to "' . $this->sourceFilename . '"', __FILE__, __LINE__); |
||||||||
956 | } elseif ($this->src) { |
||||||||
957 | $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src); |
||||||||
958 | $this->DebugMessage('$this->sourceFilename set to "' . $this->sourceFilename . '" from $this->src (' . $this->src . ')', __FILE__, __LINE__); |
||||||||
959 | } else { |
||||||||
960 | return $this->ErrorImage('$this->sourceFilename and $this->src are both empty'); |
||||||||
961 | } |
||||||||
962 | if ($this->iswindows |
||||||||
963 | && (('//' === mb_substr($this->sourceFilename, 0, 2)) |
||||||||
0 ignored issues
–
show
It seems like
$this->sourceFilename can also be of type false and null ; however, parameter $string of mb_substr() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
964 | || ('\\\\' === mb_substr($this->sourceFilename, 0, 2)))) { |
||||||||
965 | // Windows \\share\filename.ext |
||||||||
966 | } elseif (preg_match('#^[a-z0-9]+://#i', $this->sourceFilename, $protocol_matches)) { |
||||||||
0 ignored issues
–
show
It seems like
$this->sourceFilename can also be of type false and null ; however, parameter $subject of preg_match() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
967 | if (preg_match('#^(f|ht)tps?\://#i', $this->sourceFilename)) { |
||||||||
968 | // URL |
||||||||
969 | if ($this->config_http_user_agent) { |
||||||||
970 | ini_set('user_agent', $this->config_http_user_agent); |
||||||||
971 | } |
||||||||
972 | } else { |
||||||||
973 | return $this->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "' . $protocol_matches[1] . '" is not'); |
||||||||
974 | } |
||||||||
975 | } elseif (!@file_exists($this->sourceFilename)) { |
||||||||
0 ignored issues
–
show
It seems like
$this->sourceFilename can also be of type false and null ; however, parameter $filename of file_exists() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
976 | return $this->ErrorImage('"' . $this->sourceFilename . '" does not exist'); |
||||||||
977 | } elseif (!@is_file($this->sourceFilename)) { |
||||||||
0 ignored issues
–
show
It seems like
$this->sourceFilename can also be of type false and null ; however, parameter $filename of is_file() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
978 | return $this->ErrorImage('"' . $this->sourceFilename . '" is not a file'); |
||||||||
979 | } |
||||||||
980 | |||||||||
981 | return true; |
||||||||
982 | } |
||||||||
983 | |||||||||
984 | /** |
||||||||
985 | * @return bool |
||||||||
986 | */ |
||||||||
987 | public function setOutputFormat() |
||||||||
988 | { |
||||||||
989 | static $alreadyCalled = false; |
||||||||
990 | if ($this->thumbnailFormat && $alreadyCalled) { |
||||||||
991 | return true; |
||||||||
992 | } |
||||||||
993 | $alreadyCalled = true; |
||||||||
994 | |||||||||
995 | $AvailableImageOutputFormats = []; |
||||||||
996 | $AvailableImageOutputFormats[] = 'text'; |
||||||||
997 | if (@is_readable(__DIR__ . '/phpthumb.ico.php')) { |
||||||||
998 | $AvailableImageOutputFormats[] = 'ico'; |
||||||||
999 | } |
||||||||
1000 | if (@is_readable(__DIR__ . '/phpthumb.bmp.php')) { |
||||||||
1001 | $AvailableImageOutputFormats[] = 'bmp'; |
||||||||
1002 | } |
||||||||
1003 | |||||||||
1004 | $this->thumbnailFormat = 'ico'; |
||||||||
1005 | |||||||||
1006 | // Set default output format based on what image types are available |
||||||||
1007 | if (function_exists('imagetypes')) { |
||||||||
1008 | $imagetypes = imagetypes(); |
||||||||
1009 | if ($imagetypes & IMG_WBMP) { |
||||||||
1010 | $this->thumbnailFormat = 'wbmp'; |
||||||||
1011 | $AvailableImageOutputFormats[] = 'wbmp'; |
||||||||
1012 | } |
||||||||
1013 | if ($imagetypes & IMG_GIF) { |
||||||||
1014 | $this->thumbnailFormat = 'gif'; |
||||||||
1015 | $AvailableImageOutputFormats[] = 'gif'; |
||||||||
1016 | } |
||||||||
1017 | if ($imagetypes & IMG_PNG) { |
||||||||
1018 | $this->thumbnailFormat = 'png'; |
||||||||
1019 | $AvailableImageOutputFormats[] = 'png'; |
||||||||
1020 | } |
||||||||
1021 | if ($imagetypes & IMG_JPG) { |
||||||||
1022 | $this->thumbnailFormat = 'jpeg'; |
||||||||
1023 | $AvailableImageOutputFormats[] = 'jpeg'; |
||||||||
1024 | } |
||||||||
1025 | } else { |
||||||||
1026 | $this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?', __FILE__, __LINE__); |
||||||||
1027 | } |
||||||||
1028 | if ($this->ImageMagickVersion()) { |
||||||||
1029 | $IMformats = ['jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp']; |
||||||||
1030 | $this->DebugMessage('Addding ImageMagick formats to $AvailableImageOutputFormats (' . implode(';', $AvailableImageOutputFormats) . ')', __FILE__, __LINE__); |
||||||||
1031 | foreach ($IMformats as $key => $format) { |
||||||||
1032 | $AvailableImageOutputFormats[] = $format; |
||||||||
1033 | } |
||||||||
1034 | } |
||||||||
1035 | $AvailableImageOutputFormats = array_unique($AvailableImageOutputFormats); |
||||||||
1036 | $this->DebugMessage('$AvailableImageOutputFormats = array(' . implode(';', $AvailableImageOutputFormats) . ')', __FILE__, __LINE__); |
||||||||
1037 | |||||||||
1038 | $this->f = preg_replace('#[^a-z]#', '', mb_strtolower($this->f)); |
||||||||
1039 | if ('jpg' === mb_strtolower($this->config_output_format)) { |
||||||||
1040 | $this->config_output_format = 'jpeg'; |
||||||||
1041 | } |
||||||||
1042 | if ('jpg' === mb_strtolower($this->f)) { |
||||||||
1043 | $this->f = 'jpeg'; |
||||||||
1044 | } |
||||||||
1045 | if (phpthumb_functions::CaseInsensitiveInArray($this->config_output_format, $AvailableImageOutputFormats)) { |
||||||||
1046 | // set output format to config default if that format is available |
||||||||
1047 | $this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "' . mb_strtolower($this->config_output_format) . '"', __FILE__, __LINE__); |
||||||||
1048 | $this->thumbnailFormat = mb_strtolower($this->config_output_format); |
||||||||
1049 | } elseif ($this->config_output_format) { |
||||||||
1050 | $this->DebugMessage('$this->thumbnailFormat staying as "' . $this->thumbnailFormat . '" because $this->config_output_format (' . mb_strtolower($this->config_output_format) . ') is not in $AvailableImageOutputFormats', __FILE__, __LINE__); |
||||||||
1051 | } |
||||||||
1052 | if ($this->f && phpthumb_functions::CaseInsensitiveInArray($this->f, $AvailableImageOutputFormats)) { |
||||||||
1053 | // override output format if $this->f is set and that format is available |
||||||||
1054 | $this->DebugMessage('$this->thumbnailFormat set to $this->f "' . mb_strtolower($this->f) . '"', __FILE__, __LINE__); |
||||||||
1055 | $this->thumbnailFormat = mb_strtolower($this->f); |
||||||||
1056 | } elseif ($this->f) { |
||||||||
1057 | $this->DebugMessage('$this->thumbnailFormat staying as "' . $this->thumbnailFormat . '" because $this->f (' . mb_strtolower($this->f) . ') is not in $AvailableImageOutputFormats', __FILE__, __LINE__); |
||||||||
1058 | } |
||||||||
1059 | |||||||||
1060 | // for JPEG images, quality 1 (worst) to 99 (best) |
||||||||
1061 | // quality < 25 is nasty, with not much size savings - not recommended |
||||||||
1062 | // problems with 100 - invalid JPEG? |
||||||||
1063 | $this->thumbnailQuality = max(1, min(99, ($this->q ? (int)$this->q : 75))); |
||||||||
1064 | $this->DebugMessage('$this->thumbnailQuality set to "' . $this->thumbnailQuality . '"', __FILE__, __LINE__); |
||||||||
1065 | |||||||||
1066 | return true; |
||||||||
1067 | } |
||||||||
1068 | |||||||||
1069 | /** |
||||||||
1070 | * @return bool |
||||||||
1071 | */ |
||||||||
1072 | public function setCacheDirectory() |
||||||||
1073 | { |
||||||||
1074 | // resolve cache directory to absolute pathname |
||||||||
1075 | $this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "' . $this->config_cache_directory . '"', __FILE__, __LINE__); |
||||||||
1076 | if ('.' === mb_substr($this->config_cache_directory, 0, 1)) { |
||||||||
1077 | if (preg_match('#^(f|ht)tps?\://#i', $this->src)) { |
||||||||
1078 | if (!$this->config_cache_disable_warning) { |
||||||||
1079 | $this->ErrorImage('$this->config_cache_directory (' . $this->config_cache_directory . ') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php'); |
||||||||
1080 | } |
||||||||
1081 | } elseif ($this->src) { |
||||||||
1082 | // resolve relative cache directory to source image |
||||||||
1083 | $this->config_cache_directory = \dirname($this->ResolveFilenameToAbsolute($this->src)) . DIRECTORY_SEPARATOR . $this->config_cache_directory; |
||||||||
0 ignored issues
–
show
It seems like
$this->ResolveFilenameToAbsolute($this->src) can also be of type false and null ; however, parameter $path of dirname() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1084 | } |
||||||||
1085 | // $this->new is probably set |
||||||||
1086 | } |
||||||||
1087 | if ('/' === mb_substr($this->config_cache_directory, -1)) { |
||||||||
1088 | $this->config_cache_directory = mb_substr($this->config_cache_directory, 0, -1); |
||||||||
1089 | } |
||||||||
1090 | if ($this->iswindows) { |
||||||||
1091 | $this->config_cache_directory = str_replace('/', DIRECTORY_SEPARATOR, $this->config_cache_directory); |
||||||||
1092 | } |
||||||||
1093 | if ($this->config_cache_directory) { |
||||||||
1094 | $real_cache_path = $this->realPathSafe($this->config_cache_directory); |
||||||||
1095 | if (!$real_cache_path) { |
||||||||
1096 | $this->DebugMessage('$this->realPathSafe($this->config_cache_directory) failed for "' . $this->config_cache_directory . '"', __FILE__, __LINE__); |
||||||||
1097 | if (!is_dir($this->config_cache_directory)) { |
||||||||
1098 | $this->DebugMessage('!is_dir(' . $this->config_cache_directory . ')', __FILE__, __LINE__); |
||||||||
1099 | } |
||||||||
1100 | } |
||||||||
1101 | if ($real_cache_path) { |
||||||||
1102 | $this->DebugMessage('setting config_cache_directory to $this->realPathSafe(' . $this->config_cache_directory . ') = "' . $real_cache_path . '"', __FILE__, __LINE__); |
||||||||
1103 | $this->config_cache_directory = $real_cache_path; |
||||||||
1104 | } |
||||||||
1105 | } |
||||||||
1106 | if (!is_dir($this->config_cache_directory)) { |
||||||||
1107 | if (!$this->config_cache_disable_warning) { |
||||||||
1108 | $this->ErrorImage('$this->config_cache_directory (' . $this->config_cache_directory . ') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php'); |
||||||||
1109 | } |
||||||||
1110 | $this->DebugMessage('$this->config_cache_directory (' . $this->config_cache_directory . ') is not a directory', __FILE__, __LINE__); |
||||||||
1111 | $this->config_cache_directory = null; |
||||||||
1112 | } elseif (!@is_writable($this->config_cache_directory)) { |
||||||||
1113 | $this->DebugMessage('$this->config_cache_directory is not writable (' . $this->config_cache_directory . ')', __FILE__, __LINE__); |
||||||||
1114 | } |
||||||||
1115 | |||||||||
1116 | $this->InitializeTempDirSetting(); |
||||||||
1117 | if (!@is_dir($this->config_temp_directory) && !@is_writable($this->config_temp_directory) |
||||||||
1118 | && @is_dir($this->config_cache_directory) |
||||||||
1119 | && @is_writable($this->config_cache_directory)) { |
||||||||
1120 | $this->DebugMessage('setting $this->config_temp_directory = $this->config_cache_directory (' . $this->config_cache_directory . ')', __FILE__, __LINE__); |
||||||||
1121 | $this->config_temp_directory = $this->config_cache_directory; |
||||||||
1122 | } |
||||||||
1123 | |||||||||
1124 | return true; |
||||||||
1125 | } |
||||||||
1126 | |||||||||
1127 | /* Takes the array of path segments up to now, and the next segment (maybe a modifier: empty, . or ..) |
||||||||
1128 | Applies it, adding or removing from $segments as a result. Returns nothing. */ |
||||||||
1129 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1130 | |||||||||
1131 | /** |
||||||||
1132 | * @param $segments |
||||||||
1133 | * @param $segment |
||||||||
1134 | */ |
||||||||
1135 | public function applyPathSegment(&$segments, $segment) |
||||||||
1136 | { |
||||||||
1137 | if ('.' === $segment) { |
||||||||
1138 | return; // always remove |
||||||||
1139 | } |
||||||||
1140 | if ('' == $segment) { |
||||||||
1141 | $test = array_pop($segments); |
||||||||
1142 | if (null === $test) { |
||||||||
1143 | $segments[] = $segment; // keep the first empty block |
||||||||
1144 | } elseif ('' == $test) { |
||||||||
1145 | $test = array_pop($segments); |
||||||||
1146 | if (null === $test) { |
||||||||
1147 | $segments[] = $test; |
||||||||
1148 | $segments[] = $segment; // keep the second one too |
||||||||
1149 | } else { // put both back and ignore segment |
||||||||
1150 | $segments[] = $test; |
||||||||
1151 | $segments[] = $test; |
||||||||
1152 | } |
||||||||
1153 | } else { |
||||||||
1154 | $segments[] = $test; // ignore empty blocks |
||||||||
1155 | } |
||||||||
1156 | } else { |
||||||||
1157 | if ('..' === $segment) { |
||||||||
1158 | $test = array_pop($segments); |
||||||||
1159 | if (null === $test) { |
||||||||
1160 | $segments[] = $segment; |
||||||||
1161 | } elseif ('..' === $test) { |
||||||||
1162 | $segments[] = $test; |
||||||||
1163 | $segments[] = $segment; |
||||||||
1164 | } else { |
||||||||
1165 | if ('' == $test) { |
||||||||
1166 | $segments[] = $test; |
||||||||
1167 | } // else nothing, remove both |
||||||||
1168 | } |
||||||||
1169 | } else { |
||||||||
1170 | $segments[] = $segment; |
||||||||
1171 | } |
||||||||
1172 | } |
||||||||
1173 | } |
||||||||
1174 | |||||||||
1175 | /* Takes array of path components, normalizes it: removes empty slots and '.', collapses '..' and folder names. Returns array. */ |
||||||||
1176 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1177 | |||||||||
1178 | /** |
||||||||
1179 | * @param $segments |
||||||||
1180 | * @return array |
||||||||
1181 | */ |
||||||||
1182 | public function normalizePath($segments) |
||||||||
1183 | { |
||||||||
1184 | $parts = []; |
||||||||
1185 | foreach ($segments as $segment) { |
||||||||
1186 | $this->applyPathSegment($parts, $segment); |
||||||||
1187 | } |
||||||||
1188 | |||||||||
1189 | return $parts; |
||||||||
1190 | } |
||||||||
1191 | |||||||||
1192 | /* True if the provided path points (without resolving symbolic links) into one of the allowed directories. */ |
||||||||
1193 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1194 | |||||||||
1195 | /** |
||||||||
1196 | * @param $path |
||||||||
1197 | * @param $allowed_dirs |
||||||||
1198 | * @return bool |
||||||||
1199 | */ |
||||||||
1200 | public function matchPath($path, $allowed_dirs) |
||||||||
1201 | { |
||||||||
1202 | if (!empty($allowed_dirs)) { |
||||||||
1203 | foreach ($allowed_dirs as $one_dir) { |
||||||||
1204 | if (preg_match('#^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($one_dir))) . '#', $path)) { |
||||||||
1205 | return true; |
||||||||
1206 | } |
||||||||
1207 | } |
||||||||
1208 | } |
||||||||
1209 | |||||||||
1210 | return false; |
||||||||
1211 | } |
||||||||
1212 | |||||||||
1213 | /* True if the provided path points inside one of open_basedirs (or if open_basedirs are disabled) */ |
||||||||
1214 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1215 | |||||||||
1216 | /** |
||||||||
1217 | * @param $path |
||||||||
1218 | * @return bool |
||||||||
1219 | */ |
||||||||
1220 | public function isInOpenBasedir($path) |
||||||||
1221 | { |
||||||||
1222 | static $open_basedirs = null; |
||||||||
1223 | if (null === $open_basedirs) { |
||||||||
1224 | $ini_text = ini_get('open_basedir'); |
||||||||
1225 | $this->DebugMessage('open_basedir: "' . $ini_text . '"', __FILE__, __LINE__); |
||||||||
1226 | $open_basedirs = []; |
||||||||
1227 | if (mb_strlen($ini_text) > 0) { |
||||||||
1228 | foreach (preg_split('#[;:]#', $ini_text) as $key => $value) { |
||||||||
1229 | $open_basedirs[$key] = $this->realPathSafe($value); |
||||||||
1230 | } |
||||||||
1231 | } |
||||||||
1232 | } |
||||||||
1233 | |||||||||
1234 | return (empty($open_basedirs) || $this->matchPath($path, $open_basedirs)); |
||||||||
1235 | } |
||||||||
1236 | |||||||||
1237 | /* Resolves all symlinks in $path, checking that each continuous part ends in an allowed zone. Returns null, if any component leads outside of allowed zone. */ |
||||||||
1238 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1239 | |||||||||
1240 | /** |
||||||||
1241 | * @param $path |
||||||||
1242 | * @param $allowed_dirs |
||||||||
1243 | * @return null|string |
||||||||
1244 | */ |
||||||||
1245 | public function resolvePath($path, $allowed_dirs) |
||||||||
1246 | { |
||||||||
1247 | $this->DebugMessage('resolvePath: ' . $path . ' (allowed_dirs: ' . print_r($allowed_dirs, true) . ')', __FILE__, __LINE__); |
||||||||
0 ignored issues
–
show
Are you sure
print_r($allowed_dirs, true) of type string|true can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1248 | |||||||||
1249 | // add base path to the top of the list |
||||||||
1250 | if (!$this->config_allow_src_above_docroot) { |
||||||||
1251 | array_unshift($allowed_dirs, $this->realPathSafe($this->config_document_root)); |
||||||||
1252 | } else { |
||||||||
1253 | if (!$this->config_allow_src_above_phpthumb) { |
||||||||
1254 | array_unshift($allowed_dirs, $this->realPathSafe(__DIR__)); |
||||||||
1255 | } else { |
||||||||
1256 | // no checks are needed, offload the work to realpath and forget about it |
||||||||
1257 | $this->DebugMessage('resolvePath: checks disabled, returning ' . $this->realPathSafe($path), __FILE__, __LINE__); |
||||||||
1258 | |||||||||
1259 | return $this->realPathSafe($path); |
||||||||
1260 | } |
||||||||
1261 | } |
||||||||
1262 | if ('' == $path) { |
||||||||
1263 | return null; // save us trouble |
||||||||
1264 | } |
||||||||
1265 | |||||||||
1266 | do { |
||||||||
1267 | $this->DebugMessage('resolvePath: iteration, path=' . $path . ', base path = ' . $allowed_dirs[0], __FILE__, __LINE__); |
||||||||
1268 | |||||||||
1269 | $parts = []; |
||||||||
1270 | // do not use "cleaner" foreach version of this loop as later code relies on both $segments and $i |
||||||||
1271 | // http://support.silisoftware.com/phpBB3/viewtopic.php?t=964 |
||||||||
1272 | $segments = explode(DIRECTORY_SEPARATOR, $path); |
||||||||
1273 | for ($i = 0; $i < count($segments); ++$i) { |
||||||||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||||||||
1274 | $this->applyPathSegment($parts, $segments[$i]); |
||||||||
1275 | $thispart = implode(DIRECTORY_SEPARATOR, $parts); |
||||||||
1276 | if ($this->isInOpenBasedir($thispart)) { |
||||||||
1277 | if (is_link($thispart)) { |
||||||||
1278 | break; |
||||||||
1279 | } |
||||||||
1280 | } |
||||||||
1281 | } |
||||||||
1282 | |||||||||
1283 | $this->DebugMessage('resolvePath: stop at component ' . $i, __FILE__, __LINE__); |
||||||||
1284 | // test the part up to here |
||||||||
1285 | $path = implode(DIRECTORY_SEPARATOR, $parts); |
||||||||
1286 | $this->DebugMessage('resolvePath: stop at path=' . $path, __FILE__, __LINE__); |
||||||||
1287 | if (!$this->matchPath($path, $allowed_dirs)) { |
||||||||
1288 | $this->DebugMessage('resolvePath: no match, returning null', __FILE__, __LINE__); |
||||||||
1289 | |||||||||
1290 | return null; |
||||||||
1291 | } |
||||||||
1292 | if ($i >= count($segments)) { // reached end |
||||||||
1293 | $this->DebugMessage('resolvePath: path parsed, over', __FILE__, __LINE__); |
||||||||
1294 | break; |
||||||||
1295 | } |
||||||||
1296 | // else it's symlink, rewrite path |
||||||||
1297 | $path = readlink($path); |
||||||||
1298 | $this->DebugMessage('resolvePath: symlink matched, target=' . $path, __FILE__, __LINE__); |
||||||||
1299 | |||||||||
1300 | /* |
||||||||
1301 | Replace base path with symlink target. |
||||||||
1302 | Assuming: |
||||||||
1303 | /www/img/external -> /external |
||||||||
1304 | This is allowed: |
||||||||
1305 | GET /www/img/external/../external/test/pic.jpg |
||||||||
1306 | This isn't: |
||||||||
1307 | GET /www/img/external/../www/img/pic.jpg |
||||||||
1308 | So there's only one base path which is the last symlink target, but any number of stable whitelisted paths. |
||||||||
1309 | */ |
||||||||
1310 | if ($this->config_auto_allow_symlinks) { |
||||||||
1311 | $allowed_dirs[0] = $path; |
||||||||
1312 | } |
||||||||
1313 | $path = $path . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, array_slice($segments, $i + 1)); |
||||||||
1314 | } while (true); |
||||||||
1315 | |||||||||
1316 | return $path; |
||||||||
1317 | } |
||||||||
1318 | |||||||||
1319 | /** |
||||||||
1320 | * @param $filename |
||||||||
1321 | * @return bool|null|string|string[] |
||||||||
1322 | */ |
||||||||
1323 | public function realPathSafe($filename) |
||||||||
1324 | { |
||||||||
1325 | // http://php.net/manual/en/function.realpath.php -- "Note: The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE" |
||||||||
1326 | // realPathSafe() provides a reasonable facsimile of realpath() but does not resolve symbolic links, nor does it check that the file/path actually exists |
||||||||
1327 | if (!$this->config_disable_realpath) { |
||||||||
1328 | return realpath($filename); |
||||||||
1329 | } |
||||||||
1330 | |||||||||
1331 | // http://stackoverflow.com/questions/21421569 |
||||||||
1332 | $newfilename = preg_replace('#[\\/]+#', DIRECTORY_SEPARATOR, $filename); |
||||||||
1333 | if (!preg_match('#^' . DIRECTORY_SEPARATOR . '#', $newfilename)) { |
||||||||
1334 | $newfilename = __DIR__ . DIRECTORY_SEPARATOR . $newfilename; |
||||||||
1335 | } |
||||||||
1336 | do { |
||||||||
1337 | $beforeloop = $newfilename; |
||||||||
1338 | |||||||||
1339 | // Replace all sequences of more than one / with a single one [[ If you're working on a system that treats // at the start of a path as special, make sure you replace multiple / characters at the start with two of them. This is the only place where POSIX allows (but does not mandate) special handling for multiples, in all other cases, multiple / characters are equivalent to a single one.]] |
||||||||
1340 | $newfilename = preg_replace('#' . DIRECTORY_SEPARATOR . '+#', DIRECTORY_SEPARATOR, $newfilename); |
||||||||
1341 | |||||||||
1342 | // Replace all occurrences of /./ with / |
||||||||
1343 | $newfilename = preg_replace('#' . DIRECTORY_SEPARATOR . '\\.' . DIRECTORY_SEPARATOR . '#', DIRECTORY_SEPARATOR, $newfilename); |
||||||||
1344 | |||||||||
1345 | // Remove ./ if at the start |
||||||||
1346 | $newfilename = preg_replace('#^\\.' . DIRECTORY_SEPARATOR . '#', '', $newfilename); |
||||||||
1347 | |||||||||
1348 | // Remove /. if at the end |
||||||||
1349 | $newfilename = preg_replace('#' . DIRECTORY_SEPARATOR . '\\.$#', '', $newfilename); |
||||||||
1350 | |||||||||
1351 | // Replace /anything/../ with / |
||||||||
1352 | $newfilename = preg_replace('#' . DIRECTORY_SEPARATOR . '[^' . DIRECTORY_SEPARATOR . ']+' . DIRECTORY_SEPARATOR . '\\.\\.' . DIRECTORY_SEPARATOR . '#', DIRECTORY_SEPARATOR, $newfilename); |
||||||||
1353 | |||||||||
1354 | // Remove /anything/.. if at the end |
||||||||
1355 | $newfilename = preg_replace('#' . DIRECTORY_SEPARATOR . '[^' . DIRECTORY_SEPARATOR . ']+' . DIRECTORY_SEPARATOR . '\\.\\.$#', '', $newfilename); |
||||||||
1356 | } while ($newfilename != $beforeloop); |
||||||||
1357 | |||||||||
1358 | return $newfilename; |
||||||||
1359 | } |
||||||||
1360 | |||||||||
1361 | /** |
||||||||
1362 | * @param $filename |
||||||||
1363 | * @return bool|null|string|string[] |
||||||||
1364 | */ |
||||||||
1365 | public function ResolveFilenameToAbsolute($filename) |
||||||||
1366 | { |
||||||||
1367 | if (empty($filename)) { |
||||||||
1368 | return false; |
||||||||
1369 | } |
||||||||
1370 | |||||||||
1371 | if (preg_match('#^[a-z0-9]+\:/{1,2}#i', $filename)) { |
||||||||
1372 | // eg: http://host/path/file.jpg (HTTP URL) |
||||||||
1373 | // eg: ftp://host/path/file.jpg (FTP URL) |
||||||||
1374 | // eg: data1:/path/file.jpg (Netware path) |
||||||||
1375 | |||||||||
1376 | //$AbsoluteFilename = $filename; |
||||||||
1377 | return $filename; |
||||||||
1378 | } elseif ($this->iswindows && isset($filename[1]) && (':' === $filename[1])) { |
||||||||
1379 | // absolute pathname (Windows) |
||||||||
1380 | $AbsoluteFilename = $filename; |
||||||||
1381 | } elseif ($this->iswindows && (('//' === mb_substr($filename, 0, 2)) || ('\\\\' === mb_substr($filename, 0, 2)))) { |
||||||||
1382 | // absolute pathname (Windows) |
||||||||
1383 | $AbsoluteFilename = $filename; |
||||||||
1384 | } elseif ('/' === $filename[0]) { |
||||||||
1385 | if (@is_readable($filename) && !@is_readable($this->config_document_root . $filename)) { |
||||||||
0 ignored issues
–
show
Are you sure
$this->config_document_root of type mixed can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1386 | // absolute filename (*nix) |
||||||||
1387 | $AbsoluteFilename = $filename; |
||||||||
1388 | } elseif (isset($filename[1]) && ('~' === $filename[1])) { |
||||||||
1389 | // /~user/path |
||||||||
1390 | if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) { |
||||||||
1391 | $AbsoluteFilename = $ApacheLookupURIarray['filename']; |
||||||||
1392 | } else { |
||||||||
1393 | $AbsoluteFilename = $this->realPathSafe($filename); |
||||||||
1394 | if (@is_readable($AbsoluteFilename)) { |
||||||||
1395 | $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "' . $filename . '", but the correct filename (' . $AbsoluteFilename . ') seems to have been resolved with $this->realPathSafe($filename)', __FILE__, __LINE__); |
||||||||
1396 | } elseif (is_dir(dirname($AbsoluteFilename))) { |
||||||||
1397 | $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "' . \dirname($filename) . '", but the correct directory (' . \dirname($AbsoluteFilename) . ') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__); |
||||||||
1398 | } else { |
||||||||
1399 | return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "' . $filename . '". This has been known to fail on Apache2 - try using the absolute filename for the source image (ex: "/home/user/httpdocs/image.jpg" instead of "/~user/image.jpg")'); |
||||||||
1400 | } |
||||||||
1401 | } |
||||||||
1402 | } else { |
||||||||
1403 | // relative filename (any OS) |
||||||||
1404 | if (preg_match('#^' . preg_quote($this->config_document_root) . '#', $filename)) { |
||||||||
0 ignored issues
–
show
It seems like
$this->config_document_root can also be of type mixed ; however, parameter $str of preg_quote() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1405 | $AbsoluteFilename = $filename; |
||||||||
1406 | $this->DebugMessage('ResolveFilenameToAbsolute() NOT prepending $this->config_document_root (' . $this->config_document_root . ') to $filename (' . $filename . ') resulting in ($AbsoluteFilename = "' . $AbsoluteFilename . '")', __FILE__, __LINE__); |
||||||||
1407 | } else { |
||||||||
1408 | $AbsoluteFilename = $this->config_document_root . $filename; |
||||||||
1409 | $this->DebugMessage('ResolveFilenameToAbsolute() prepending $this->config_document_root (' . $this->config_document_root . ') to $filename (' . $filename . ') resulting in ($AbsoluteFilename = "' . $AbsoluteFilename . '")', __FILE__, __LINE__); |
||||||||
1410 | } |
||||||||
1411 | } |
||||||||
1412 | } else { |
||||||||
1413 | // relative to current directory (any OS) |
||||||||
1414 | $AbsoluteFilename = __DIR__ . DIRECTORY_SEPARATOR . preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename); |
||||||||
1415 | |||||||||
1416 | if ('/~' === mb_substr(dirname(@$_SERVER['PHP_SELF']), 0, 2)) { |
||||||||
1417 | if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) { |
||||||||
1418 | $AbsoluteFilename = $ApacheLookupURIarray['filename'] . DIRECTORY_SEPARATOR . $filename; |
||||||||
1419 | } else { |
||||||||
1420 | $AbsoluteFilename = $this->realPathSafe('.') . DIRECTORY_SEPARATOR . $filename; |
||||||||
1421 | if (@is_readable($AbsoluteFilename)) { |
||||||||
1422 | $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "' . \dirname(@$_SERVER['PHP_SELF']) . '", but the correct filename (' . $AbsoluteFilename . ') seems to have been resolved with $this->realPathSafe(.)/$filename', __FILE__, __LINE__); |
||||||||
1423 | } elseif (is_dir(dirname($AbsoluteFilename))) { |
||||||||
1424 | $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "' . \dirname(@$_SERVER['PHP_SELF']) . '", but the correct directory (' . \dirname($AbsoluteFilename) . ') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__); |
||||||||
1425 | } else { |
||||||||
1426 | return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "' . \dirname(@$_SERVER['PHP_SELF']) . '". This has been known to fail on Apache2 - try using the absolute filename for the source image'); |
||||||||
1427 | } |
||||||||
1428 | } |
||||||||
1429 | } |
||||||||
1430 | } |
||||||||
1431 | /* |
||||||||
1432 | // removed 2014-May-30: http://support.silisoftware.com/phpBB3/viewtopic.php?t=961 |
||||||||
1433 | if (is_link($AbsoluteFilename)) { |
||||||||
1434 | $this->DebugMessage('is_link()==true, changing "'.$AbsoluteFilename.'" to "'.readlink($AbsoluteFilename).'"', __FILE__, __LINE__); |
||||||||
1435 | $AbsoluteFilename = readlink($AbsoluteFilename); |
||||||||
1436 | } |
||||||||
1437 | if ($this->realPathSafe($AbsoluteFilename)) { |
||||||||
1438 | $AbsoluteFilename = $this->realPathSafe($AbsoluteFilename); |
||||||||
1439 | } |
||||||||
1440 | */ |
||||||||
1441 | if ($this->iswindows) { |
||||||||
1442 | $AbsoluteFilename = preg_replace('#^' . preg_quote($this->realPathSafe($this->config_document_root)) . '#i', str_replace('\\', '\\\\', $this->realPathSafe($this->config_document_root)), $AbsoluteFilename); |
||||||||
1443 | $AbsoluteFilename = str_replace(DIRECTORY_SEPARATOR, '/', $AbsoluteFilename); |
||||||||
1444 | } |
||||||||
1445 | $AbsoluteFilename = $this->resolvePath($AbsoluteFilename, $this->config_additional_allowed_dirs); |
||||||||
1446 | if (!$this->config_allow_src_above_docroot |
||||||||
1447 | && !preg_match('#^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($this->config_document_root))) . '#', $AbsoluteFilename)) { |
||||||||
0 ignored issues
–
show
It seems like
$AbsoluteFilename can also be of type null ; however, parameter $subject of preg_match() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1448 | $this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "' . $AbsoluteFilename . '" (outside "' . $this->realPathSafe($this->config_document_root) . '") to null', __FILE__, __LINE__); |
||||||||
1449 | |||||||||
1450 | return false; |
||||||||
1451 | } |
||||||||
1452 | if (!$this->config_allow_src_above_phpthumb |
||||||||
1453 | && !preg_match('#^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', __DIR__)) . '#', $AbsoluteFilename)) { |
||||||||
1454 | $this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "' . $AbsoluteFilename . '" (outside "' . __DIR__ . '") to null', __FILE__, __LINE__); |
||||||||
1455 | |||||||||
1456 | return false; |
||||||||
1457 | } |
||||||||
1458 | |||||||||
1459 | return $AbsoluteFilename; |
||||||||
1460 | } |
||||||||
1461 | |||||||||
1462 | /** |
||||||||
1463 | * @param $filename |
||||||||
1464 | * @param bool $cached |
||||||||
1465 | * @return mixed |
||||||||
1466 | */ |
||||||||
1467 | public function file_exists_ignoreopenbasedir($filename, $cached = true) |
||||||||
1468 | { |
||||||||
1469 | static $open_basedirs = null; |
||||||||
1470 | static $file_exists_cache = []; |
||||||||
1471 | if (!$cached || !isset($file_exists_cache[$filename])) { |
||||||||
1472 | if (null === $open_basedirs) { |
||||||||
1473 | $open_basedirs = preg_split('#[;:]#', ini_get('open_basedir')); |
||||||||
1474 | } |
||||||||
1475 | if (empty($open_basedirs) || in_array(dirname($filename), $open_basedirs, true)) { |
||||||||
1476 | $file_exists_cache[$filename] = file_exists($filename); |
||||||||
1477 | } elseif ($this->iswindows) { |
||||||||
1478 | $ls_filename = trim(phpthumb_functions::SafeExec('dir /b ' . phpthumb_functions::escapeshellarg_replacement($filename))); |
||||||||
0 ignored issues
–
show
It seems like
phpthumb_functions::Safe...replacement($filename)) can also be of type false ; however, parameter $string of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1479 | $file_exists_cache[$filename] = ($ls_filename == basename($filename)); // command dir /b return only filename without path |
||||||||
1480 | } else { |
||||||||
1481 | $ls_filename = trim(phpthumb_functions::SafeExec('ls ' . phpthumb_functions::escapeshellarg_replacement($filename))); |
||||||||
1482 | $file_exists_cache[$filename] = ($ls_filename == $filename); |
||||||||
1483 | } |
||||||||
1484 | } |
||||||||
1485 | |||||||||
1486 | return $file_exists_cache[$filename]; |
||||||||
1487 | } |
||||||||
1488 | |||||||||
1489 | /** |
||||||||
1490 | * @return bool|null|string |
||||||||
1491 | */ |
||||||||
1492 | public function ImageMagickWhichConvert() |
||||||||
1493 | { |
||||||||
1494 | static $WhichConvert = null; |
||||||||
1495 | if (null === $WhichConvert) { |
||||||||
1496 | if ($this->iswindows) { |
||||||||
1497 | $WhichConvert = false; |
||||||||
1498 | } else { |
||||||||
1499 | $IMwhichConvertCacheFilename = $this->config_cache_directory . DIRECTORY_SEPARATOR . 'phpThumbCacheIMwhichConvert.txt'; |
||||||||
1500 | if (false !== ($cachedwhichconvertstring = @file_get_contents($IMwhichConvertCacheFilename))) { |
||||||||
1501 | $WhichConvert = $cachedwhichconvertstring; |
||||||||
1502 | } else { |
||||||||
1503 | $WhichConvert = trim(phpthumb_functions::SafeExec('which convert')); |
||||||||
0 ignored issues
–
show
It seems like
phpthumb_functions::SafeExec('which convert') can also be of type false ; however, parameter $string of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1504 | @file_put_contents($IMwhichConvertCacheFilename, $WhichConvert); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
file_put_contents() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
1505 | } |
||||||||
1506 | } |
||||||||
1507 | } |
||||||||
1508 | |||||||||
1509 | return $WhichConvert; |
||||||||
1510 | } |
||||||||
1511 | |||||||||
1512 | /** |
||||||||
1513 | * @return bool|null|string |
||||||||
1514 | */ |
||||||||
1515 | public function ImageMagickCommandlineBase() |
||||||||
1516 | { |
||||||||
1517 | static $commandline = null; |
||||||||
1518 | if (null === $commandline) { |
||||||||
1519 | if ($this->issafemode) { |
||||||||
1520 | $commandline = ''; |
||||||||
1521 | |||||||||
1522 | return $commandline; |
||||||||
1523 | } |
||||||||
1524 | |||||||||
1525 | $IMcommandlineBaseCacheFilename = $this->config_cache_directory . DIRECTORY_SEPARATOR . 'phpThumbCacheIMcommandlineBase.txt'; |
||||||||
1526 | if (false !== ($commandline = @file_get_contents($IMcommandlineBaseCacheFilename))) { |
||||||||
1527 | return $commandline; |
||||||||
1528 | } |
||||||||
1529 | |||||||||
1530 | $commandline = (null !== $this->config_imagemagick_path ? $this->config_imagemagick_path : ''); |
||||||||
0 ignored issues
–
show
|
|||||||||
1531 | |||||||||
1532 | if ($this->config_imagemagick_path |
||||||||
1533 | && ($this->config_imagemagick_path != $this->realPathSafe($this->config_imagemagick_path))) { |
||||||||
1534 | if (@is_executable($this->realPathSafe($this->config_imagemagick_path))) { |
||||||||
1535 | $this->DebugMessage('Changing $this->config_imagemagick_path (' . $this->config_imagemagick_path . ') to $this->realPathSafe($this->config_imagemagick_path) (' . $this->realPathSafe($this->config_imagemagick_path) . ')', __FILE__, __LINE__); |
||||||||
1536 | $this->config_imagemagick_path = $this->realPathSafe($this->config_imagemagick_path); |
||||||||
1537 | } else { |
||||||||
1538 | $this->DebugMessage('Leaving $this->config_imagemagick_path as (' . $this->config_imagemagick_path . ') because !is_execuatable($this->realPathSafe($this->config_imagemagick_path)) (' . $this->realPathSafe($this->config_imagemagick_path) . ')', __FILE__, __LINE__); |
||||||||
1539 | } |
||||||||
1540 | } |
||||||||
1541 | $this->DebugMessage(' file_exists(' . $this->config_imagemagick_path . ') = ' . (int)(@file_exists($this->config_imagemagick_path)), __FILE__, __LINE__); |
||||||||
1542 | $this->DebugMessage('file_exists_ignoreopenbasedir(' . $this->config_imagemagick_path . ') = ' . (int)$this->file_exists_ignoreopenbasedir($this->config_imagemagick_path), __FILE__, __LINE__); |
||||||||
1543 | $this->DebugMessage(' is_file(' . $this->config_imagemagick_path . ') = ' . (int)(@is_file($this->config_imagemagick_path)), __FILE__, __LINE__); |
||||||||
1544 | $this->DebugMessage(' is_executable(' . $this->config_imagemagick_path . ') = ' . (int)(@is_executable($this->config_imagemagick_path)), __FILE__, __LINE__); |
||||||||
1545 | |||||||||
1546 | if ($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)) { |
||||||||
1547 | $this->DebugMessage('using ImageMagick path from $this->config_imagemagick_path (' . $this->config_imagemagick_path . ')', __FILE__, __LINE__); |
||||||||
1548 | if ($this->iswindows) { |
||||||||
1549 | $commandline = mb_substr($this->config_imagemagick_path, 0, 2) . ' && cd ' . phpthumb_functions::escapeshellarg_replacement(str_replace('/', DIRECTORY_SEPARATOR, mb_substr(dirname($this->config_imagemagick_path), 2))) . ' && ' . phpthumb_functions::escapeshellarg_replacement( |
||||||||
1550 | basename($this->config_imagemagick_path) |
||||||||
1551 | ); |
||||||||
1552 | } else { |
||||||||
1553 | $commandline = phpthumb_functions::escapeshellarg_replacement($this->config_imagemagick_path); |
||||||||
1554 | } |
||||||||
1555 | } else { |
||||||||
1556 | $which_convert = $this->ImageMagickWhichConvert(); |
||||||||
1557 | $IMversion = $this->ImageMagickVersion(); |
||||||||
1558 | |||||||||
1559 | if ($which_convert && ('/' === $which_convert[0]) |
||||||||
1560 | && $this->file_exists_ignoreopenbasedir($which_convert)) { |
||||||||
1561 | // `which convert` *should* return the path if "convert" exist, or nothing if it doesn't |
||||||||
1562 | // other things *may* get returned, like "sh: convert: not found" or "no convert in /usr/local/bin /usr/sbin /usr/bin /usr/ccs/bin" |
||||||||
1563 | // so only do this if the value returned exists as a file |
||||||||
1564 | $this->DebugMessage('using ImageMagick path from `which convert` (' . $which_convert . ')', __FILE__, __LINE__); |
||||||||
1565 | $commandline = 'convert'; |
||||||||
1566 | } elseif ($IMversion) { |
||||||||
1567 | $this->DebugMessage('setting ImageMagick path to $this->config_imagemagick_path (' . $this->config_imagemagick_path . ') [' . $IMversion . ']', __FILE__, __LINE__); |
||||||||
1568 | $commandline = $this->config_imagemagick_path; |
||||||||
1569 | } else { |
||||||||
1570 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting because cannot find convert in $this->config_imagemagick_path (' . $this->config_imagemagick_path . '), and `which convert` returned (' . $which_convert . ')', __FILE__, __LINE__); |
||||||||
1571 | $commandline = ''; |
||||||||
1572 | } |
||||||||
1573 | } |
||||||||
1574 | |||||||||
1575 | @file_put_contents($IMcommandlineBaseCacheFilename, $commandline); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
file_put_contents() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
1576 | } |
||||||||
1577 | |||||||||
1578 | return $commandline; |
||||||||
1579 | } |
||||||||
1580 | |||||||||
1581 | /** |
||||||||
1582 | * @param bool $returnRAW |
||||||||
1583 | * @return mixed |
||||||||
1584 | */ |
||||||||
1585 | public function ImageMagickVersion($returnRAW = false) |
||||||||
1586 | { |
||||||||
1587 | static $versionstring = null; |
||||||||
1588 | if (null === $versionstring) { |
||||||||
1589 | $versionstring = [0 => false, 1 => false]; |
||||||||
1590 | |||||||||
1591 | $IMversionCacheFilename = $this->config_cache_directory . DIRECTORY_SEPARATOR . 'phpThumbCacheIMversion.txt'; |
||||||||
1592 | if ($cachedversionstring = @file_get_contents($IMversionCacheFilename)) { |
||||||||
1593 | $versionstring = explode("\n", $cachedversionstring, 2); |
||||||||
1594 | $versionstring[0] = ($versionstring[0] ?: false); // "false" is stored as an empty string in the cache file |
||||||||
1595 | $versionstring[1] = ($versionstring[1] ?: false); // "false" is stored as an empty string in the cache file |
||||||||
1596 | } else { |
||||||||
1597 | $commandline = $this->ImageMagickCommandlineBase(); |
||||||||
1598 | $commandline = (null !== $commandline ? $commandline : ''); |
||||||||
1599 | if ($commandline) { |
||||||||
1600 | $commandline .= ' --version'; |
||||||||
1601 | $this->DebugMessage('ImageMagick version checked with "' . $commandline . '"', __FILE__, __LINE__); |
||||||||
1602 | $versionstring[1] = trim(phpthumb_functions::SafeExec($commandline)); |
||||||||
0 ignored issues
–
show
It seems like
phpthumb_functions::SafeExec($commandline) can also be of type false ; however, parameter $string of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1603 | if (preg_match('#^Version: [^0-9]*([ 0-9\\.\\:Q/\\-]+)#i', $versionstring[1], $matches)) { |
||||||||
1604 | $versionstring[0] = trim($matches[1]); |
||||||||
1605 | } else { |
||||||||
1606 | $versionstring[0] = false; |
||||||||
1607 | $this->DebugMessage('ImageMagick did not return recognized version string (' . $versionstring[1] . ')', __FILE__, __LINE__); |
||||||||
1608 | } |
||||||||
1609 | $this->DebugMessage('ImageMagick convert --version says "' . @$matches[0] . '"', __FILE__, __LINE__); |
||||||||
1610 | } |
||||||||
1611 | |||||||||
1612 | @file_put_contents($IMversionCacheFilename, $versionstring[0] . "\n" . $versionstring[1]); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
file_put_contents() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
1613 | } |
||||||||
1614 | } |
||||||||
1615 | |||||||||
1616 | return $versionstring[(int)$returnRAW]; |
||||||||
1617 | } |
||||||||
1618 | |||||||||
1619 | /** |
||||||||
1620 | * @param $switchname |
||||||||
1621 | * @return bool |
||||||||
1622 | */ |
||||||||
1623 | public function ImageMagickSwitchAvailable($switchname) |
||||||||
1624 | { |
||||||||
1625 | static $IMoptions = null; |
||||||||
1626 | if (null === $IMoptions) { |
||||||||
1627 | $IMoptions = []; |
||||||||
1628 | $commandline = $this->ImageMagickCommandlineBase(); |
||||||||
1629 | if (null !== $commandline) { |
||||||||
1630 | $commandline .= ' -help'; |
||||||||
1631 | $IMhelp_lines = explode("\n", phpthumb_functions::SafeExec($commandline)); |
||||||||
0 ignored issues
–
show
It seems like
phpthumb_functions::SafeExec($commandline) can also be of type false ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1632 | foreach ($IMhelp_lines as $line) { |
||||||||
1633 | if (preg_match('#^[\\+\\-]([a-z\\-]+) #', trim($line), $matches)) { |
||||||||
1634 | $IMoptions[$matches[1]] = true; |
||||||||
1635 | } |
||||||||
1636 | } |
||||||||
1637 | } |
||||||||
1638 | } |
||||||||
1639 | if (is_array($switchname)) { |
||||||||
1640 | $allOK = true; |
||||||||
1641 | foreach ($switchname as $key => $value) { |
||||||||
1642 | if (!isset($IMoptions[$value])) { |
||||||||
1643 | $allOK = false; |
||||||||
1644 | break; |
||||||||
1645 | } |
||||||||
1646 | } |
||||||||
1647 | $this->DebugMessage('ImageMagickSwitchAvailable(' . implode(';', $switchname) . ') = ' . (int)$allOK . '', __FILE__, __LINE__); |
||||||||
1648 | } else { |
||||||||
1649 | $allOK = isset($IMoptions[$switchname]); |
||||||||
1650 | $this->DebugMessage('ImageMagickSwitchAvailable(' . $switchname . ') = ' . (int)$allOK . '', __FILE__, __LINE__); |
||||||||
1651 | } |
||||||||
1652 | |||||||||
1653 | return $allOK; |
||||||||
1654 | } |
||||||||
1655 | |||||||||
1656 | /** |
||||||||
1657 | * @return bool|null|string |
||||||||
1658 | */ |
||||||||
1659 | public function ImageMagickFormatsList() |
||||||||
1660 | { |
||||||||
1661 | static $IMformatsList = null; |
||||||||
1662 | if (null === $IMformatsList) { |
||||||||
1663 | $IMformatsList = ''; |
||||||||
1664 | $commandline = $this->ImageMagickCommandlineBase(); |
||||||||
1665 | if (null !== $commandline) { |
||||||||
1666 | $commandline = \dirname($commandline) . DIRECTORY_SEPARATOR . str_replace('convert', 'identify', basename($commandline)); |
||||||||
1667 | $commandline .= ' -list format'; |
||||||||
1668 | $IMformatsList = phpthumb_functions::SafeExec($commandline); |
||||||||
1669 | } |
||||||||
1670 | } |
||||||||
1671 | |||||||||
1672 | return $IMformatsList; |
||||||||
1673 | } |
||||||||
1674 | |||||||||
1675 | /** |
||||||||
1676 | * @return bool |
||||||||
1677 | */ |
||||||||
1678 | public function SourceDataToTempFile() |
||||||||
1679 | { |
||||||||
1680 | if ($IMtempSourceFilename = $this->phpThumb_tempnam()) { |
||||||||
1681 | $IMtempSourceFilename = $this->realPathSafe($IMtempSourceFilename); |
||||||||
1682 | ob_start(); |
||||||||
1683 | $fp_tempfile = fopen($IMtempSourceFilename, 'wb'); |
||||||||
1684 | $tempfile_open_error = ob_get_contents(); |
||||||||
1685 | ob_end_clean(); |
||||||||
1686 | if ($fp_tempfile) { |
||||||||
0 ignored issues
–
show
|
|||||||||
1687 | fwrite($fp_tempfile, $this->rawImageData); |
||||||||
1688 | fclose($fp_tempfile); |
||||||||
1689 | $this->sourceFilename = $IMtempSourceFilename; |
||||||||
1690 | $this->DebugMessage('ImageMagickThumbnailToGD() setting $this->sourceFilename to "' . $IMtempSourceFilename . '" from $this->rawImageData (' . mb_strlen($this->rawImageData) . ' bytes)', __FILE__, __LINE__); |
||||||||
1691 | } else { |
||||||||
1692 | $this->DebugMessage('ImageMagickThumbnailToGD() FAILED setting $this->sourceFilename to "' . $IMtempSourceFilename . '" (failed to open for writing: "' . $tempfile_open_error . '")', __FILE__, __LINE__); |
||||||||
1693 | } |
||||||||
1694 | unset($tempfile_open_error, $IMtempSourceFilename); |
||||||||
1695 | |||||||||
1696 | return true; |
||||||||
1697 | } |
||||||||
1698 | $this->DebugMessage('SourceDataToTempFile() FAILED because $this->phpThumb_tempnam() failed', __FILE__, __LINE__); |
||||||||
1699 | |||||||||
1700 | return false; |
||||||||
1701 | } |
||||||||
1702 | |||||||||
1703 | /** |
||||||||
1704 | * @return bool |
||||||||
1705 | */ |
||||||||
1706 | public function ImageMagickThumbnailToGD() |
||||||||
1707 | { |
||||||||
1708 | // http://www.imagemagick.org/script/command-line-options.php |
||||||||
1709 | |||||||||
1710 | $this->useRawIMoutput = true; |
||||||||
1711 | if (phpthumb_functions::gd_version()) { |
||||||||
1712 | // if GD is not available, must use whatever ImageMagick can output |
||||||||
1713 | |||||||||
1714 | // $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick |
||||||||
1715 | // note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below |
||||||||
1716 | $UnAllowedParameters = ['xto', 'ar', 'bg', 'bc']; |
||||||||
1717 | // 'ra' may be part of this list, if not a multiple of 90 degrees |
||||||||
1718 | foreach ($UnAllowedParameters as $parameter) { |
||||||||
1719 | if (isset($this->$parameter)) { |
||||||||
1720 | $this->DebugMessage('$this->useRawIMoutput=false because "' . $parameter . '" is set', __FILE__, __LINE__); |
||||||||
1721 | $this->useRawIMoutput = false; |
||||||||
1722 | break; |
||||||||
1723 | } |
||||||||
1724 | } |
||||||||
1725 | } |
||||||||
1726 | $this->DebugMessage('$this->useRawIMoutput=' . ($this->useRawIMoutput ? 'true' : 'false') . ' after checking $UnAllowedParameters', __FILE__, __LINE__); |
||||||||
1727 | $ImageCreateFunction = ''; |
||||||||
1728 | $outputFormat = $this->thumbnailFormat; |
||||||||
1729 | if (phpthumb_functions::gd_version()) { |
||||||||
1730 | if ($this->useRawIMoutput) { |
||||||||
1731 | switch ($this->thumbnailFormat) { |
||||||||
1732 | case 'gif': |
||||||||
1733 | $ImageCreateFunction = 'imagecreatefromgif'; |
||||||||
1734 | $this->is_alpha = true; |
||||||||
1735 | break; |
||||||||
1736 | case 'png': |
||||||||
1737 | $ImageCreateFunction = 'imagecreatefrompng'; |
||||||||
1738 | $this->is_alpha = true; |
||||||||
1739 | break; |
||||||||
1740 | case 'jpg': |
||||||||
1741 | case 'jpeg': |
||||||||
1742 | $ImageCreateFunction = 'imagecreatefromjpeg'; |
||||||||
1743 | break; |
||||||||
1744 | default: |
||||||||
1745 | $this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat (' . $this->thumbnailFormat . ' is not a GD-supported format)', __FILE__, __LINE__); |
||||||||
1746 | $outputFormat = 'png'; |
||||||||
1747 | $ImageCreateFunction = 'imagecreatefrompng'; |
||||||||
1748 | $this->is_alpha = true; |
||||||||
1749 | $this->useRawIMoutput = false; |
||||||||
1750 | break; |
||||||||
1751 | } |
||||||||
1752 | if (!function_exists(@$ImageCreateFunction)) { |
||||||||
1753 | // ImageMagickThumbnailToGD() depends on imagecreatefrompng/imagecreatefromgif |
||||||||
1754 | //$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__); |
||||||||
1755 | $this->useRawIMoutput = true; |
||||||||
1756 | //return false; |
||||||||
1757 | } |
||||||||
1758 | } else { |
||||||||
1759 | $outputFormat = 'png'; |
||||||||
1760 | $ImageCreateFunction = 'imagecreatefrompng'; |
||||||||
1761 | $this->is_alpha = true; |
||||||||
1762 | $this->useRawIMoutput = false; |
||||||||
1763 | } |
||||||||
1764 | } |
||||||||
1765 | |||||||||
1766 | // http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html |
||||||||
1767 | if (!$this->sourceFilename && $this->rawImageData) { |
||||||||
1768 | $this->SourceDataToTempFile(); |
||||||||
1769 | } |
||||||||
1770 | if (!$this->sourceFilename) { |
||||||||
1771 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__); |
||||||||
1772 | $this->useRawIMoutput = false; |
||||||||
1773 | |||||||||
1774 | return false; |
||||||||
1775 | } |
||||||||
1776 | if ($this->issafemode) { |
||||||||
1777 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__); |
||||||||
1778 | $this->useRawIMoutput = false; |
||||||||
1779 | |||||||||
1780 | return false; |
||||||||
1781 | } |
||||||||
1782 | // TO BE FIXED |
||||||||
1783 | //if (true) { |
||||||||
1784 | // $this->DebugMessage('ImageMagickThumbnailToGD() aborting it is broken right now', __FILE__, __LINE__); |
||||||||
1785 | // $this->useRawIMoutput = false; |
||||||||
1786 | // return false; |
||||||||
1787 | //} |
||||||||
1788 | |||||||||
1789 | $commandline = $this->ImageMagickCommandlineBase(); |
||||||||
1790 | if ($commandline) { |
||||||||
1791 | if ($IMtempfilename = $this->phpThumb_tempnam()) { |
||||||||
1792 | $IMtempfilename = $this->realPathSafe($IMtempfilename); |
||||||||
1793 | |||||||||
1794 | $IMuseExplicitImageOutputDimensions = false; |
||||||||
1795 | if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) { |
||||||||
1796 | $IMresizeParameter = 'thumbnail'; |
||||||||
1797 | } else { |
||||||||
1798 | $IMresizeParameter = 'resize'; |
||||||||
1799 | |||||||||
1800 | // some (older? around 2002) versions of IM won't accept "-resize 100x" but require "-resize 100x100" |
||||||||
1801 | $commandline_test = $this->ImageMagickCommandlineBase() . ' logo: -resize 1x ' . phpthumb_functions::escapeshellarg_replacement($IMtempfilename) . ' 2>&1'; |
||||||||
1802 | $IMresult_test = phpthumb_functions::SafeExec($commandline_test); |
||||||||
1803 | $IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test); |
||||||||
0 ignored issues
–
show
It seems like
$IMresult_test can also be of type false ; however, parameter $subject of preg_match() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1804 | $this->DebugMessage('IMuseExplicitImageOutputDimensions = ' . (int)$IMuseExplicitImageOutputDimensions, __FILE__, __LINE__); |
||||||||
1805 | if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) { |
||||||||
1806 | // erase temp image so ImageMagick logo doesn't get output if other processing fails |
||||||||
1807 | fclose($fp_im_temp); |
||||||||
1808 | } |
||||||||
1809 | } |
||||||||
1810 | |||||||||
1811 | if (null !== $this->dpi && $this->ImageMagickSwitchAvailable('density')) { |
||||||||
1812 | // for vector source formats only (WMF, PDF, etc) |
||||||||
1813 | $commandline .= ' -flatten -density ' . phpthumb_functions::escapeshellarg_replacement($this->dpi); |
||||||||
1814 | } |
||||||||
1815 | ob_start(); |
||||||||
1816 | $getimagesize = getimagesize($this->sourceFilename); |
||||||||
1817 | $GetImageSizeError = ob_get_contents(); |
||||||||
1818 | ob_end_clean(); |
||||||||
1819 | if (is_array($getimagesize)) { |
||||||||
0 ignored issues
–
show
|
|||||||||
1820 | $this->DebugMessage('getimagesize(' . $this->sourceFilename . ') SUCCEEDED: ' . print_r($getimagesize, true), __FILE__, __LINE__); |
||||||||
0 ignored issues
–
show
Are you sure
print_r($getimagesize, true) of type string|true can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1821 | } else { |
||||||||
1822 | $this->DebugMessage('getimagesize(' . $this->sourceFilename . ') FAILED with error "' . $GetImageSizeError . '"', __FILE__, __LINE__); |
||||||||
1823 | } |
||||||||
1824 | if (is_array($getimagesize)) { |
||||||||
0 ignored issues
–
show
|
|||||||||
1825 | $this->DebugMessage('getimagesize(' . $this->sourceFilename . ') returned [w=' . $getimagesize[0] . ';h=' . $getimagesize[1] . ';f=' . $getimagesize[2] . ']', __FILE__, __LINE__); |
||||||||
1826 | $this->source_width = $getimagesize[0]; |
||||||||
1827 | $this->source_height = $getimagesize[1]; |
||||||||
1828 | $this->DebugMessage('source dimensions set to ' . $this->source_width . 'x' . $this->source_height, __FILE__, __LINE__); |
||||||||
1829 | $this->SetOrientationDependantWidthHeight(); |
||||||||
1830 | |||||||||
1831 | if (!preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat)) { |
||||||||
1832 | // not a transparency-capable format |
||||||||
1833 | $commandline .= ' -background ' . phpthumb_functions::escapeshellarg_replacement('#' . ($this->bg ?: 'FFFFFF')); |
||||||||
1834 | if (IMAGETYPE_GIF == $getimagesize[2]) { |
||||||||
1835 | $commandline .= ' -flatten'; |
||||||||
1836 | } |
||||||||
1837 | } |
||||||||
1838 | if (IMAGETYPE_GIF == $getimagesize[2]) { |
||||||||
1839 | $commandline .= ' -coalesce'; // may be needed for animated GIFs |
||||||||
1840 | } |
||||||||
1841 | if ($this->source_width || $this->source_height) { |
||||||||
1842 | if ($this->zc) { |
||||||||
1843 | $borderThickness = 0; |
||||||||
1844 | if (!empty($this->fltr)) { |
||||||||
1845 | foreach ($this->fltr as $key => $value) { |
||||||||
1846 | if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) { |
||||||||
1847 | $borderThickness = $matches[1]; |
||||||||
1848 | break; |
||||||||
1849 | } |
||||||||
1850 | } |
||||||||
1851 | } |
||||||||
1852 | $wAll = (int)max($this->w, $this->wp, $this->wl, $this->ws) - (2 * $borderThickness); |
||||||||
1853 | $hAll = (int)max($this->h, $this->hp, $this->hl, $this->hs) - (2 * $borderThickness); |
||||||||
1854 | $imAR = $this->source_width / $this->source_height; |
||||||||
1855 | $zcAR = (($wAll && $hAll) ? $wAll / $hAll : 1); |
||||||||
1856 | $side = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll)); |
||||||||
1857 | $sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR)); |
||||||||
0 ignored issues
–
show
|
|||||||||
1858 | $sideY = phpthumb_functions::nonempty_min($this->source_height, $hAll, round($wAll / $zcAR)); |
||||||||
1859 | |||||||||
1860 | $thumbnailH = round(max($sideY, ($sideY * $zcAR) / $imAR)); |
||||||||
1861 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement(($IMuseExplicitImageOutputDimensions ? $thumbnailH : '') . 'x' . $thumbnailH); |
||||||||
1862 | |||||||||
1863 | switch (mb_strtoupper($this->zc)) { |
||||||||
1864 | case 'T': |
||||||||
1865 | $commandline .= ' -gravity north'; |
||||||||
1866 | break; |
||||||||
1867 | case 'B': |
||||||||
1868 | $commandline .= ' -gravity south'; |
||||||||
1869 | break; |
||||||||
1870 | case 'L': |
||||||||
1871 | $commandline .= ' -gravity west'; |
||||||||
1872 | break; |
||||||||
1873 | case 'R': |
||||||||
1874 | $commandline .= ' -gravity east'; |
||||||||
1875 | break; |
||||||||
1876 | case 'TL': |
||||||||
1877 | $commandline .= ' -gravity northwest'; |
||||||||
1878 | break; |
||||||||
1879 | case 'TR': |
||||||||
1880 | $commandline .= ' -gravity northeast'; |
||||||||
1881 | break; |
||||||||
1882 | case 'BL': |
||||||||
1883 | $commandline .= ' -gravity southwest'; |
||||||||
1884 | break; |
||||||||
1885 | case 'BR': |
||||||||
1886 | $commandline .= ' -gravity southeast'; |
||||||||
1887 | break; |
||||||||
1888 | case '1': |
||||||||
1889 | case 'C': |
||||||||
1890 | default: |
||||||||
1891 | $commandline .= ' -gravity center'; |
||||||||
1892 | break; |
||||||||
1893 | } |
||||||||
1894 | |||||||||
1895 | if (($wAll > 0) && ($hAll > 0)) { |
||||||||
1896 | $commandline .= ' -crop ' . phpthumb_functions::escapeshellarg_replacement($wAll . 'x' . $hAll . '+0+0'); |
||||||||
1897 | } else { |
||||||||
1898 | $commandline .= ' -crop ' . phpthumb_functions::escapeshellarg_replacement($side . 'x' . $side . '+0+0'); |
||||||||
1899 | } |
||||||||
1900 | if ($this->ImageMagickSwitchAvailable('repage')) { |
||||||||
1901 | $commandline .= ' +repage'; |
||||||||
1902 | } else { |
||||||||
1903 | $this->DebugMessage('Skipping "+repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); |
||||||||
1904 | } |
||||||||
1905 | } elseif ($this->sw || $this->sh || $this->sx || $this->sy) { |
||||||||
1906 | $crop_param = ''; |
||||||||
1907 | $crop_param .= ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width) : $this->sw) : $this->source_width); |
||||||||
1908 | $crop_param .= 'x' . ($this->sh ? (($this->sh < 2) ? round($this->sh * $this->source_height) : $this->sh) : $this->source_height); |
||||||||
1909 | $crop_param .= '+' . (($this->sx < 2) ? round($this->sx * $this->source_width) : $this->sx); |
||||||||
1910 | $crop_param .= '+' . (($this->sy < 2) ? round($this->sy * $this->source_height) : $this->sy); |
||||||||
1911 | // TO BE FIXED |
||||||||
1912 | // makes 1x1 output |
||||||||
1913 | // http://trainspotted.com/phpThumb/phpThumb.php?src=/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg&w=100&h=100&far=1&f=png&fltr[]=lvl&sx=0.05&sy=0.25&sw=0.92&sh=0.42 |
||||||||
1914 | // '/usr/bin/convert' -density 150 -thumbnail 100x100 -contrast-stretch '0.1%' '/var/www/vhosts/trainspotted.com/httpdocs/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg[0]' png:'/var/www/vhosts/trainspotted.com/httpdocs/phpThumb/_cache/pThumbIIUlvj' |
||||||||
1915 | $commandline .= ' -crop ' . phpthumb_functions::escapeshellarg_replacement($crop_param); |
||||||||
1916 | |||||||||
1917 | // this is broken for aoe=1, but unsure how to fix. Send advice to [email protected] |
||||||||
1918 | if ($this->w || $this->h) { |
||||||||
1919 | //if ($this->ImageMagickSwitchAvailable('repage')) { |
||||||||
1920 | if (false) { |
||||||||
1921 | // TO BE FIXED |
||||||||
1922 | // newer versions of ImageMagick require -repage <geometry> |
||||||||
1923 | $commandline .= ' -repage'; |
||||||||
1924 | } else { |
||||||||
1925 | $this->DebugMessage('Skipping "-repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); |
||||||||
1926 | } |
||||||||
1927 | if ($IMuseExplicitImageOutputDimensions) { |
||||||||
0 ignored issues
–
show
The expression
$IMuseExplicitImageOutputDimensions of type false|integer is loosely compared to true ; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||||||||
1928 | if ($this->w && !$this->h) { |
||||||||
1929 | $this->h = ceil($this->w / ($this->source_width / $this->source_height)); |
||||||||
1930 | } elseif ($this->h && !$this->w) { |
||||||||
1931 | $this->w = ceil($this->h * ($this->source_width / $this->source_height)); |
||||||||
1932 | } |
||||||||
1933 | } |
||||||||
1934 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement($this->w . 'x' . $this->h); |
||||||||
1935 | } |
||||||||
1936 | } else { |
||||||||
1937 | if ($this->iar && ((int)$this->w > 0) && ((int)$this->h > 0)) { |
||||||||
1938 | [$nw, $nh] = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); |
||||||||
1939 | $nw = ((0 != round($nw)) ? round($nw) : ''); |
||||||||
1940 | $nh = ((0 != round($nh)) ? round($nh) : ''); |
||||||||
1941 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement($nw . 'x' . $nh . '!'); |
||||||||
1942 | } else { |
||||||||
1943 | $this->w = ((($this->aoe || $this->far) |
||||||||
1944 | && $this->w) ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : '')); |
||||||||
1945 | $this->h = ((($this->aoe || $this->far) |
||||||||
1946 | && $this->h) ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : '')); |
||||||||
1947 | if ($this->w || $this->h) { |
||||||||
1948 | if ($IMuseExplicitImageOutputDimensions) { |
||||||||
0 ignored issues
–
show
The expression
$IMuseExplicitImageOutputDimensions of type false|integer is loosely compared to true ; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||||||||
1949 | if ($this->w && !$this->h) { |
||||||||
1950 | $this->h = ceil($this->w / ($this->source_width / $this->source_height)); |
||||||||
1951 | } elseif ($this->h && !$this->w) { |
||||||||
1952 | $this->w = ceil($this->h * ($this->source_width / $this->source_height)); |
||||||||
1953 | } |
||||||||
1954 | } |
||||||||
1955 | [$nw, $nh] = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); |
||||||||
1956 | $nw = ((0 != round($nw)) ? round($nw) : ''); |
||||||||
1957 | $nh = ((0 != round($nh)) ? round($nh) : ''); |
||||||||
1958 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement($nw . 'x' . $nh); |
||||||||
1959 | } |
||||||||
1960 | } |
||||||||
1961 | } |
||||||||
1962 | } |
||||||||
1963 | } else { |
||||||||
1964 | $this->DebugMessage('getimagesize(' . $this->sourceFilename . ') failed', __FILE__, __LINE__); |
||||||||
1965 | if ($this->w || $this->h) { |
||||||||
1966 | $exactDimensionsBang = (($this->iar && ((int)$this->w > 0) |
||||||||
1967 | && ((int)$this->h > 0)) ? '!' : ''); |
||||||||
1968 | if ($IMuseExplicitImageOutputDimensions) { |
||||||||
1969 | // unknown source aspect ratio, just put large number and hope IM figures it out |
||||||||
1970 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement(($this->w ?: '9999') . 'x' . ($this->h ?: '9999') . $exactDimensionsBang); |
||||||||
1971 | } else { |
||||||||
1972 | $commandline .= ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement($this->w . 'x' . $this->h . $exactDimensionsBang); |
||||||||
1973 | } |
||||||||
1974 | } |
||||||||
1975 | } |
||||||||
1976 | |||||||||
1977 | if ($this->ra) { |
||||||||
1978 | $this->ra = (int)$this->ra; |
||||||||
1979 | if ($this->ImageMagickSwitchAvailable('rotate')) { |
||||||||
1980 | if (!preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat) |
||||||||
1981 | || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) { |
||||||||
1982 | $this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__); |
||||||||
1983 | $commandline .= ' -rotate ' . phpthumb_functions::escapeshellarg_replacement($this->ra); |
||||||||
1984 | if (0 != ($this->ra % 90)) { |
||||||||
1985 | if (preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat)) { |
||||||||
1986 | // alpha-capable format |
||||||||
1987 | $commandline .= ' -background rgba(255,255,255,0)'; |
||||||||
1988 | } else { |
||||||||
1989 | $commandline .= ' -background ' . phpthumb_functions::escapeshellarg_replacement('#' . ($this->bg ?: 'FFFFFF')); |
||||||||
1990 | } |
||||||||
1991 | } |
||||||||
1992 | $this->ra = 0; |
||||||||
1993 | } else { |
||||||||
1994 | $this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__); |
||||||||
1995 | } |
||||||||
1996 | } else { |
||||||||
1997 | $this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__); |
||||||||
1998 | } |
||||||||
1999 | } |
||||||||
2000 | |||||||||
2001 | $successfullyProcessedFilters = []; |
||||||||
2002 | foreach ($this->fltr as $filterkey => $filtercommand) { |
||||||||
2003 | @list($command, $parameter) = explode('|', $filtercommand, 2); |
||||||||
2004 | switch ($command) { |
||||||||
2005 | case 'brit': |
||||||||
2006 | if ($this->ImageMagickSwitchAvailable('modulate')) { |
||||||||
2007 | $commandline .= ' -modulate ' . phpthumb_functions::escapeshellarg_replacement((100 + (int)$parameter) . ',100,100'); |
||||||||
2008 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2009 | } |
||||||||
2010 | break; |
||||||||
2011 | case 'cont': |
||||||||
2012 | if ($this->ImageMagickSwitchAvailable('contrast')) { |
||||||||
2013 | $contDiv10 = round((int)$parameter / 10); |
||||||||
2014 | if ($contDiv10 > 0) { |
||||||||
2015 | $contDiv10 = min($contDiv10, 100); |
||||||||
2016 | for ($i = 0; $i < $contDiv10; ++$i) { |
||||||||
2017 | $commandline .= ' -contrast'; // increase contrast by 10% |
||||||||
2018 | } |
||||||||
2019 | } elseif ($contDiv10 < 0) { |
||||||||
2020 | $contDiv10 = max($contDiv10, -100); |
||||||||
2021 | for ($i = $contDiv10; $i < 0; ++$i) { |
||||||||
2022 | $commandline .= ' +contrast'; // decrease contrast by 10% |
||||||||
2023 | } |
||||||||
2024 | } |
||||||||
2025 | // do nothing |
||||||||
2026 | |||||||||
2027 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2028 | } |
||||||||
2029 | break; |
||||||||
2030 | case 'ds': |
||||||||
2031 | if ($this->ImageMagickSwitchAvailable(['colorspace', 'modulate'])) { |
||||||||
2032 | if (100 == $parameter) { |
||||||||
2033 | $commandline .= ' -colorspace GRAY'; |
||||||||
2034 | $commandline .= ' -modulate 100,0,100'; |
||||||||
2035 | } else { |
||||||||
2036 | $commandline .= ' -modulate ' . phpthumb_functions::escapeshellarg_replacement('100,' . (100 - (int)$parameter) . ',100'); |
||||||||
2037 | } |
||||||||
2038 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2039 | } |
||||||||
2040 | break; |
||||||||
2041 | case 'sat': |
||||||||
2042 | if ($this->ImageMagickSwitchAvailable(['colorspace', 'modulate'])) { |
||||||||
2043 | if (-100 == $parameter) { |
||||||||
2044 | $commandline .= ' -colorspace GRAY'; |
||||||||
2045 | $commandline .= ' -modulate 100,0,100'; |
||||||||
2046 | } else { |
||||||||
2047 | $commandline .= ' -modulate ' . phpthumb_functions::escapeshellarg_replacement('100,' . (100 + (int)$parameter) . ',100'); |
||||||||
2048 | } |
||||||||
2049 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2050 | } |
||||||||
2051 | break; |
||||||||
2052 | case 'gray': |
||||||||
2053 | if ($this->ImageMagickSwitchAvailable(['colorspace', 'modulate'])) { |
||||||||
2054 | $commandline .= ' -colorspace GRAY'; |
||||||||
2055 | $commandline .= ' -modulate 100,0,100'; |
||||||||
2056 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2057 | } |
||||||||
2058 | break; |
||||||||
2059 | case 'clr': |
||||||||
2060 | if ($this->ImageMagickSwitchAvailable(['fill', 'colorize'])) { |
||||||||
2061 | @list($amount, $color) = explode('|', $parameter); |
||||||||
2062 | $commandline .= ' -fill ' . phpthumb_functions::escapeshellarg_replacement('#' . preg_replace('#[^0-9A-F]#i', '', $color)); |
||||||||
2063 | $commandline .= ' -colorize ' . phpthumb_functions::escapeshellarg_replacement(min(max((int)$amount, 0), 100)); |
||||||||
2064 | } |
||||||||
2065 | break; |
||||||||
2066 | case 'sep': |
||||||||
2067 | if ($this->ImageMagickSwitchAvailable('sepia-tone')) { |
||||||||
2068 | @list($amount, $color) = explode('|', $parameter); |
||||||||
2069 | $amount = ($amount ?: 80); |
||||||||
2070 | if (!$color) { |
||||||||
2071 | $commandline .= ' -sepia-tone ' . phpthumb_functions::escapeshellarg_replacement(min(max($amount, 0), 100) . '%'); |
||||||||
2072 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2073 | } |
||||||||
2074 | } |
||||||||
2075 | break; |
||||||||
2076 | case 'gam': |
||||||||
2077 | @list($amount) = explode('|', $parameter); |
||||||||
2078 | $amount = min(max((float)$amount, 0.001), 10); |
||||||||
2079 | if ('1.000' !== number_format($amount, 3)) { |
||||||||
2080 | if ($this->ImageMagickSwitchAvailable('gamma')) { |
||||||||
2081 | $commandline .= ' -gamma ' . phpthumb_functions::escapeshellarg_replacement($amount); |
||||||||
2082 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2083 | } |
||||||||
2084 | } |
||||||||
2085 | break; |
||||||||
2086 | case 'neg': |
||||||||
2087 | if ($this->ImageMagickSwitchAvailable('negate')) { |
||||||||
2088 | $commandline .= ' -negate'; |
||||||||
2089 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2090 | } |
||||||||
2091 | break; |
||||||||
2092 | case 'th': |
||||||||
2093 | @list($amount) = explode('|', $parameter); |
||||||||
2094 | if ($this->ImageMagickSwitchAvailable(['threshold', 'dither', 'monochrome'])) { |
||||||||
2095 | $commandline .= ' -threshold ' . phpthumb_functions::escapeshellarg_replacement(round(min(max((int)$amount, 0), 255) / 2.55) . '%'); |
||||||||
2096 | $commandline .= ' -dither'; |
||||||||
2097 | $commandline .= ' -monochrome'; |
||||||||
2098 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2099 | } |
||||||||
2100 | break; |
||||||||
2101 | case 'rcd': |
||||||||
2102 | if ($this->ImageMagickSwitchAvailable(['colors', 'dither'])) { |
||||||||
2103 | @list($colors, $dither) = explode('|', $parameter); |
||||||||
2104 | $colors = ($colors ? (int)$colors : 256); |
||||||||
2105 | $dither = ((mb_strlen($dither) > 0) ? (bool)$dither : true); |
||||||||
2106 | $commandline .= ' -colors ' . phpthumb_functions::escapeshellarg_replacement(max($colors, 8)); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors" |
||||||||
2107 | $commandline .= ($dither ? ' -dither' : ' +dither'); |
||||||||
2108 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2109 | } |
||||||||
2110 | break; |
||||||||
2111 | case 'flip': |
||||||||
2112 | if ($this->ImageMagickSwitchAvailable(['flip', 'flop'])) { |
||||||||
2113 | if (false !== mb_strpos(mb_strtolower($parameter), 'x')) { |
||||||||
2114 | $commandline .= ' -flop'; |
||||||||
2115 | } |
||||||||
2116 | if (false !== mb_strpos(mb_strtolower($parameter), 'y')) { |
||||||||
2117 | $commandline .= ' -flip'; |
||||||||
2118 | } |
||||||||
2119 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2120 | } |
||||||||
2121 | break; |
||||||||
2122 | case 'edge': |
||||||||
2123 | if ($this->ImageMagickSwitchAvailable('edge')) { |
||||||||
2124 | $parameter = (!empty($parameter) ? $parameter : 2); |
||||||||
2125 | $commandline .= ' -edge ' . phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? $parameter : 1); |
||||||||
2126 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2127 | } |
||||||||
2128 | break; |
||||||||
2129 | case 'emb': |
||||||||
2130 | if ($this->ImageMagickSwitchAvailable(['emboss', 'negate'])) { |
||||||||
2131 | $parameter = (!empty($parameter) ? $parameter : 2); |
||||||||
2132 | $commandline .= ' -emboss ' . phpthumb_functions::escapeshellarg_replacement($parameter); |
||||||||
2133 | if ($parameter < 2) { |
||||||||
2134 | $commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1'; |
||||||||
2135 | } |
||||||||
2136 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2137 | } |
||||||||
2138 | break; |
||||||||
2139 | case 'lvl': |
||||||||
2140 | @list($band, $method, $threshold) = explode('|', $parameter); |
||||||||
2141 | $band = ($band ? preg_replace('#[^RGBA\\*]#', '', mb_strtoupper($band)) : '*'); |
||||||||
2142 | $method = ((mb_strlen($method) > 0) ? (int)$method : 2); |
||||||||
2143 | $threshold = ((mb_strlen($threshold) > 0) ? min(max((float)$threshold, 0), 100) : 0.1); |
||||||||
2144 | |||||||||
2145 | $band = preg_replace('#[^RGBA\\*]#', '', mb_strtoupper($band)); |
||||||||
2146 | |||||||||
2147 | if (($method > 1) |
||||||||
2148 | && !$this->ImageMagickSwitchAvailable([ |
||||||||
2149 | 'channel', |
||||||||
2150 | 'contrast-stretch', |
||||||||
2151 | ])) { |
||||||||
2152 | // Because ImageMagick processing happens before PHP-GD filters, and because some |
||||||||
2153 | // clipping is involved in the "lvl" filter, if "lvl" happens before "wb" then the |
||||||||
2154 | // "wb" filter will have (almost) no effect. Therefore, if "wb" is enabled then |
||||||||
2155 | // force the "lvl" filter to be processed by GD, not ImageMagick. |
||||||||
2156 | foreach ($this->fltr as $fltr_key => $fltr_value) { |
||||||||
2157 | [$fltr_cmd] = explode('|', $fltr_value); |
||||||||
2158 | if ('wb' === $fltr_cmd) { |
||||||||
2159 | $this->DebugMessage('Setting "lvl" filter method to "0" (from "' . $method . '") because white-balance filter also enabled', __FILE__, __LINE__); |
||||||||
2160 | $method = 0; |
||||||||
2161 | } |
||||||||
2162 | } |
||||||||
2163 | } |
||||||||
2164 | |||||||||
2165 | switch ($method) { |
||||||||
2166 | case 0: // internal RGB |
||||||||
2167 | case 1: // internal grayscale |
||||||||
2168 | break; |
||||||||
2169 | case 2: // ImageMagick "contrast-stretch" |
||||||||
2170 | if ($this->ImageMagickSwitchAvailable('contrast-stretch')) { |
||||||||
2171 | if ('*' !== $band) { |
||||||||
2172 | $commandline .= ' -channel ' . phpthumb_functions::escapeshellarg_replacement(mb_strtoupper($band)); |
||||||||
2173 | } |
||||||||
2174 | $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure |
||||||||
2175 | //$commandline .= ' -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); |
||||||||
2176 | $commandline .= ' -contrast-stretch \'' . $threshold . '%\''; |
||||||||
2177 | if ('*' !== $band) { |
||||||||
2178 | $commandline .= ' +channel'; |
||||||||
2179 | } |
||||||||
2180 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2181 | } |
||||||||
2182 | break; |
||||||||
2183 | case 3: // ImageMagick "normalize" |
||||||||
2184 | if ($this->ImageMagickSwitchAvailable('normalize')) { |
||||||||
2185 | if ('*' !== $band) { |
||||||||
2186 | $commandline .= ' -channel ' . phpthumb_functions::escapeshellarg_replacement(mb_strtoupper($band)); |
||||||||
2187 | } |
||||||||
2188 | $commandline .= ' -normalize'; |
||||||||
2189 | if ('*' !== $band) { |
||||||||
2190 | $commandline .= ' +channel'; |
||||||||
2191 | } |
||||||||
2192 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2193 | } |
||||||||
2194 | break; |
||||||||
2195 | default: |
||||||||
2196 | $this->DebugMessage('unsupported method (' . $method . ') for "lvl" filter', __FILE__, __LINE__); |
||||||||
2197 | break; |
||||||||
2198 | } |
||||||||
2199 | if (isset($this->fltr[$filterkey]) && ($method > 1)) { |
||||||||
2200 | $this->fltr[$filterkey] = $command . '|' . $band . '|0|' . $threshold; |
||||||||
2201 | $this->DebugMessage('filter "lvl" remapped from method "' . $method . '" to method "0" because ImageMagick support is missing', __FILE__, __LINE__); |
||||||||
2202 | } |
||||||||
2203 | break; |
||||||||
2204 | case 'wb': |
||||||||
2205 | if ($this->ImageMagickSwitchAvailable(['channel', 'contrast-stretch'])) { |
||||||||
2206 | @list($threshold) = explode('|', $parameter); |
||||||||
2207 | $threshold = (!empty($threshold) ? min(max((float)$threshold, 0), 100) : 0.1); |
||||||||
2208 | $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure |
||||||||
2209 | //$commandline .= ' -channel R -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // doesn't work on Windows because most versions of PHP do not properly |
||||||||
2210 | //$commandline .= ' -channel G -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // escape special characters (such as %) and just replace them with spaces |
||||||||
2211 | //$commandline .= ' -channel B -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // https://bugs.php.net/bug.php?id=43261 |
||||||||
2212 | $commandline .= ' -channel R -contrast-stretch \'' . $threshold . '%\''; |
||||||||
2213 | $commandline .= ' -channel G -contrast-stretch \'' . $threshold . '%\''; |
||||||||
2214 | $commandline .= ' -channel B -contrast-stretch \'' . $threshold . '%\''; |
||||||||
2215 | $commandline .= ' +channel'; |
||||||||
2216 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2217 | } |
||||||||
2218 | break; |
||||||||
2219 | case 'blur': |
||||||||
2220 | if ($this->ImageMagickSwitchAvailable('blur')) { |
||||||||
2221 | @list($radius) = explode('|', $parameter); |
||||||||
2222 | $radius = (!empty($radius) ? min(max((int)$radius, 0), 25) : 1); |
||||||||
2223 | $commandline .= ' -blur ' . phpthumb_functions::escapeshellarg_replacement($radius); |
||||||||
2224 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2225 | } |
||||||||
2226 | break; |
||||||||
2227 | case 'gblr': |
||||||||
2228 | @list($radius) = explode('|', $parameter); |
||||||||
2229 | $radius = (!empty($radius) ? min(max((int)$radius, 0), 25) : 1); |
||||||||
2230 | // "-gaussian" changed to "-gaussian-blur" sometime around 2009 |
||||||||
2231 | if ($this->ImageMagickSwitchAvailable('gaussian-blur')) { |
||||||||
2232 | $commandline .= ' -gaussian-blur ' . phpthumb_functions::escapeshellarg_replacement($radius); |
||||||||
2233 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2234 | } elseif ($this->ImageMagickSwitchAvailable('gaussian')) { |
||||||||
2235 | $commandline .= ' -gaussian ' . phpthumb_functions::escapeshellarg_replacement($radius); |
||||||||
2236 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2237 | } |
||||||||
2238 | break; |
||||||||
2239 | case 'usm': |
||||||||
2240 | if ($this->ImageMagickSwitchAvailable('unsharp')) { |
||||||||
2241 | @list($amount, $radius, $threshold) = explode('|', $parameter); |
||||||||
2242 | $amount = ($amount ? min(max((int)$radius, 0), 255) : 80); |
||||||||
2243 | $radius = ($radius ? min(max((int)$radius, 0), 10) : 0.5); |
||||||||
2244 | $threshold = (mb_strlen($threshold) ? min(max((int)$radius, 0), 50) : 3); |
||||||||
2245 | $commandline .= ' -unsharp ' . phpthumb_functions::escapeshellarg_replacement(number_format(($radius * 2) - 1, 2, '.', '') . 'x1+' . number_format($amount / 100, 2, '.', '') . '+' . number_format($threshold / 100, 2, '.', '')); |
||||||||
2246 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2247 | } |
||||||||
2248 | break; |
||||||||
2249 | case 'bord': |
||||||||
2250 | if ($this->ImageMagickSwitchAvailable([ |
||||||||
2251 | 'border', |
||||||||
2252 | 'bordercolor', |
||||||||
2253 | 'thumbnail', |
||||||||
2254 | 'crop', |
||||||||
2255 | ])) { |
||||||||
2256 | if (!$this->zc) { |
||||||||
2257 | @list($width, $rX, $rY, $color) = explode('|', $parameter); |
||||||||
2258 | $width = (int)$width; |
||||||||
2259 | $rX = (int)$rX; |
||||||||
2260 | $rY = (int)$rY; |
||||||||
2261 | if ($width && !$rX && !$rY) { |
||||||||
2262 | if (!phpthumb_functions::IsHexColor($color)) { |
||||||||
2263 | $color = ((!empty($this->bc) |
||||||||
2264 | && phpthumb_functions::IsHexColor($this->bc)) ? $this->bc : '000000'); |
||||||||
2265 | } |
||||||||
2266 | $commandline .= ' -border ' . phpthumb_functions::escapeshellarg_replacement($width); |
||||||||
2267 | $commandline .= ' -bordercolor ' . phpthumb_functions::escapeshellarg_replacement('#' . $color); |
||||||||
2268 | |||||||||
2269 | if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) { |
||||||||
2270 | $commandline = str_replace(' -crop "' . $matches[1] . 'x' . $matches[2] . '+0+0" ', ' -crop ' . phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)) . 'x' . ($matches[2] - (2 * $width)) . '+0+0') . ' ', $commandline); |
||||||||
2271 | } elseif (preg_match('# \\-' . $IMresizeParameter . ' "([0-9]+)x([0-9]+)" #', $commandline, $matches)) { |
||||||||
2272 | $commandline = str_replace( |
||||||||
2273 | ' -' . $IMresizeParameter . ' "' . $matches[1] . 'x' . $matches[2] . '" ', |
||||||||
2274 | ' -' . $IMresizeParameter . ' ' . phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)) . 'x' . ($matches[2] - (2 * $width))) . ' ', |
||||||||
2275 | $commandline |
||||||||
2276 | ); |
||||||||
2277 | } |
||||||||
2278 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2279 | } |
||||||||
2280 | } |
||||||||
2281 | } |
||||||||
2282 | break; |
||||||||
2283 | case 'crop': |
||||||||
2284 | break; |
||||||||
2285 | case 'sblr': |
||||||||
2286 | break; |
||||||||
2287 | case 'mean': |
||||||||
2288 | break; |
||||||||
2289 | case 'smth': |
||||||||
2290 | break; |
||||||||
2291 | case 'bvl': |
||||||||
2292 | break; |
||||||||
2293 | case 'wmi': |
||||||||
2294 | break; |
||||||||
2295 | case 'wmt': |
||||||||
2296 | break; |
||||||||
2297 | case 'over': |
||||||||
2298 | break; |
||||||||
2299 | case 'hist': |
||||||||
2300 | break; |
||||||||
2301 | case 'fram': |
||||||||
2302 | break; |
||||||||
2303 | case 'drop': |
||||||||
2304 | break; |
||||||||
2305 | case 'mask': |
||||||||
2306 | break; |
||||||||
2307 | case 'elip': |
||||||||
2308 | break; |
||||||||
2309 | case 'ric': |
||||||||
2310 | break; |
||||||||
2311 | case 'stc': |
||||||||
2312 | break; |
||||||||
2313 | case 'size': |
||||||||
2314 | break; |
||||||||
2315 | default: |
||||||||
2316 | $this->DebugMessage('Unknown $this->fltr[' . $filterkey . '] (' . $filtercommand . ') -- deleting filter command', __FILE__, __LINE__); |
||||||||
2317 | $successfullyProcessedFilters[] = $filterkey; |
||||||||
2318 | break; |
||||||||
2319 | } |
||||||||
2320 | if (!isset($this->fltr[$filterkey])) { |
||||||||
2321 | $this->DebugMessage('Processed $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); |
||||||||
2322 | } else { |
||||||||
2323 | $this->DebugMessage('Skipping $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); |
||||||||
2324 | } |
||||||||
2325 | } |
||||||||
2326 | $this->DebugMessage('Remaining $this->fltr after ImageMagick: (' . $this->phpThumbDebugVarDump($this->fltr) . ')', __FILE__, __LINE__); |
||||||||
2327 | if (count($this->fltr) > 0) { |
||||||||
2328 | $this->useRawIMoutput = false; |
||||||||
2329 | } |
||||||||
2330 | |||||||||
2331 | if (preg_match('#jpe?g#i', $outputFormat) && $this->q) { |
||||||||
2332 | if ($this->ImageMagickSwitchAvailable(['quality', 'interlace'])) { |
||||||||
2333 | $commandline .= ' -quality ' . phpthumb_functions::escapeshellarg_replacement($this->thumbnailQuality); |
||||||||
2334 | if ($this->config_output_interlace) { |
||||||||
2335 | // causes weird things with animated GIF... leave for JPEG only |
||||||||
2336 | $commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image |
||||||||
2337 | } |
||||||||
2338 | } |
||||||||
2339 | } |
||||||||
2340 | $commandline .= ' ' . phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename) . (('gif' === $outputFormat) ? '' : '[' . (int)$this->sfn . ']')); // [0] means first frame of (GIF) animation, can be ignored |
||||||||
2341 | $commandline .= ' ' . $outputFormat . ':' . phpthumb_functions::escapeshellarg_replacement($IMtempfilename); |
||||||||
2342 | if (!$this->iswindows) { |
||||||||
2343 | $commandline .= ' 2>&1'; |
||||||||
2344 | } |
||||||||
2345 | $this->DebugMessage('ImageMagick called as (' . $commandline . ')', __FILE__, __LINE__); |
||||||||
2346 | $IMresult = phpthumb_functions::SafeExec($commandline); |
||||||||
2347 | clearstatcache(); |
||||||||
2348 | if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) { |
||||||||
2349 | $this->FatalError('ImageMagick failed with message (' . trim($IMresult) . ')'); |
||||||||
0 ignored issues
–
show
It seems like
$IMresult can also be of type false ; however, parameter $string of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
2350 | $this->DebugMessage('ImageMagick failed with message (' . trim($IMresult) . ')', __FILE__, __LINE__); |
||||||||
2351 | if ($this->iswindows && !$IMresult) { |
||||||||
2352 | $this->DebugMessage('Check to make sure that PHP has read+write permissions to "' . \dirname($IMtempfilename) . '"', __FILE__, __LINE__); |
||||||||
2353 | } |
||||||||
2354 | } else { |
||||||||
2355 | foreach ($successfullyProcessedFilters as $dummy => $filterkey) { |
||||||||
2356 | unset($this->fltr[$filterkey]); |
||||||||
2357 | } |
||||||||
2358 | $this->IMresizedData = file_get_contents($IMtempfilename); |
||||||||
2359 | $getimagesize_imresized = @getimagesize($IMtempfilename); |
||||||||
2360 | $this->DebugMessage('getimagesize(' . $IMtempfilename . ') returned [w=' . $getimagesize_imresized[0] . ';h=' . $getimagesize_imresized[1] . ';f=' . $getimagesize_imresized[2] . ']', __FILE__, __LINE__); |
||||||||
2361 | if (($this->config_max_source_pixels > 0) |
||||||||
2362 | && ($this->config_max_source_pixels < ($getimagesize_imresized[0] * $getimagesize_imresized[1]))) { |
||||||||
2363 | $this->DebugMessage( |
||||||||
2364 | 'skipping ImageMagickThumbnailToGD::' |
||||||||
2365 | . $ImageCreateFunction |
||||||||
2366 | . '() because IM output is too large (' |
||||||||
2367 | . $getimagesize_imresized[0] |
||||||||
2368 | . 'x' |
||||||||
2369 | . $getimagesize_imresized[0] |
||||||||
2370 | . ' = ' |
||||||||
2371 | . ($getimagesize_imresized[0] * $getimagesize_imresized[1]) |
||||||||
2372 | . ' > ' |
||||||||
2373 | . $this->config_max_source_pixels |
||||||||
2374 | . ')', |
||||||||
2375 | __FILE__, |
||||||||
2376 | __LINE__ |
||||||||
2377 | ); |
||||||||
2378 | } elseif (function_exists(@$ImageCreateFunction) |
||||||||
2379 | && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) { |
||||||||
2380 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
2381 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
2382 | $this->DebugMessage('ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() succeeded, $this->gdimg_source is now (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); |
||||||||
2383 | $this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData (' . mb_strlen($this->IMresizedData) . ' bytes)', __FILE__, __LINE__); |
||||||||
2384 | } else { |
||||||||
2385 | $this->useRawIMoutput = true; |
||||||||
2386 | $this->DebugMessage('$this->useRawIMoutput set to TRUE because ' . @$ImageCreateFunction . '(' . $IMtempfilename . ') failed', __FILE__, __LINE__); |
||||||||
2387 | } |
||||||||
2388 | if (file_exists($IMtempfilename)) { |
||||||||
2389 | $this->DebugMessage('deleting "' . $IMtempfilename . '"', __FILE__, __LINE__); |
||||||||
2390 | @unlink($IMtempfilename); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
2391 | } |
||||||||
2392 | |||||||||
2393 | return true; |
||||||||
2394 | } |
||||||||
2395 | if (file_exists($IMtempfilename)) { |
||||||||
2396 | $this->DebugMessage('deleting "' . $IMtempfilename . '"', __FILE__, __LINE__); |
||||||||
2397 | @unlink($IMtempfilename); |
||||||||
2398 | } |
||||||||
2399 | } elseif ($this->issafemode) { |
||||||||
2400 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting because PHP safe_mode is enabled and phpThumb_tempnam() failed', __FILE__, __LINE__); |
||||||||
2401 | $this->useRawIMoutput = false; |
||||||||
2402 | } else { |
||||||||
2403 | if (file_exists($IMtempfilename)) { |
||||||||
2404 | $this->DebugMessage('deleting "' . $IMtempfilename . '"', __FILE__, __LINE__); |
||||||||
2405 | @unlink($IMtempfilename); |
||||||||
2406 | } |
||||||||
2407 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__); |
||||||||
2408 | } |
||||||||
2409 | } else { |
||||||||
2410 | $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__); |
||||||||
2411 | } |
||||||||
2412 | $this->useRawIMoutput = false; |
||||||||
2413 | |||||||||
2414 | return false; |
||||||||
2415 | } |
||||||||
2416 | |||||||||
2417 | /** |
||||||||
2418 | * @return bool |
||||||||
2419 | */ |
||||||||
2420 | public function Rotate() |
||||||||
2421 | { |
||||||||
2422 | if ($this->ra || $this->ar) { |
||||||||
2423 | if (!function_exists('imagerotate')) { |
||||||||
2424 | $this->DebugMessage('!function_exists(imagerotate)', __FILE__, __LINE__); |
||||||||
2425 | |||||||||
2426 | return false; |
||||||||
2427 | } |
||||||||
2428 | if (!require_once __DIR__ . '/phpthumb.filters.php') { |
||||||||
2429 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.filters.php" which is required for applying filters (' . implode(';', $this->fltr) . ')', __FILE__, __LINE__); |
||||||||
2430 | |||||||||
2431 | return false; |
||||||||
2432 | } |
||||||||
2433 | |||||||||
2434 | $this->config_background_hexcolor = ($this->bg ?: $this->config_background_hexcolor); |
||||||||
2435 | if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) { |
||||||||
2436 | return $this->ErrorImage('Invalid hex color string "' . $this->config_background_hexcolor . '" for parameter "bg"'); |
||||||||
2437 | } |
||||||||
2438 | |||||||||
2439 | $rotate_angle = 0; |
||||||||
2440 | if ($this->ra) { |
||||||||
2441 | $rotate_angle = (float)$this->ra; |
||||||||
2442 | } else { |
||||||||
2443 | if ('x' === $this->ar) { |
||||||||
2444 | if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=')) { |
||||||||
2445 | if ($this->sourceFilename) { |
||||||||
2446 | if (function_exists('exif_read_data')) { |
||||||||
2447 | if ($exif_data = @exif_read_data($this->sourceFilename, 'IFD0')) { |
||||||||
2448 | // http://sylvana.net/jpegcrop/exif_orientation.html |
||||||||
2449 | switch (@$exif_data['Orientation']) { |
||||||||
2450 | case 1: |
||||||||
2451 | $rotate_angle = 0; |
||||||||
2452 | break; |
||||||||
2453 | case 3: |
||||||||
2454 | $rotate_angle = 180; |
||||||||
2455 | break; |
||||||||
2456 | case 6: |
||||||||
2457 | $rotate_angle = 270; |
||||||||
2458 | break; |
||||||||
2459 | case 8: |
||||||||
2460 | $rotate_angle = 90; |
||||||||
2461 | break; |
||||||||
2462 | default: |
||||||||
2463 | $this->DebugMessage('EXIF auto-rotate failed because unknown $exif_data[Orientation] "' . @$exif_data['Orientation'] . '"', __FILE__, __LINE__); |
||||||||
2464 | |||||||||
2465 | return false; |
||||||||
2466 | break; |
||||||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||||||
2467 | } |
||||||||
2468 | $this->DebugMessage('EXIF auto-rotate set to ' . $rotate_angle . ' degrees ($exif_data[Orientation] = "' . @$exif_data['Orientation'] . '")', __FILE__, __LINE__); |
||||||||
2469 | } else { |
||||||||
2470 | $this->DebugMessage('failed: exif_read_data(' . $this->sourceFilename . ')', __FILE__, __LINE__); |
||||||||
2471 | |||||||||
2472 | return false; |
||||||||
2473 | } |
||||||||
2474 | } else { |
||||||||
2475 | $this->DebugMessage('!function_exists(exif_read_data)', __FILE__, __LINE__); |
||||||||
2476 | |||||||||
2477 | return false; |
||||||||
2478 | } |
||||||||
2479 | } else { |
||||||||
2480 | $this->DebugMessage('Cannot auto-rotate from EXIF data because $this->sourceFilename is empty', __FILE__, __LINE__); |
||||||||
2481 | |||||||||
2482 | return false; |
||||||||
2483 | } |
||||||||
2484 | } else { |
||||||||
2485 | $this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 (' . PHP_VERSION . ')', __FILE__, __LINE__); |
||||||||
2486 | |||||||||
2487 | return false; |
||||||||
2488 | } |
||||||||
2489 | } elseif (('l' === $this->ar) && ($this->source_height > $this->source_width)) { |
||||||||
2490 | $rotate_angle = 270; |
||||||||
2491 | } elseif (('L' === $this->ar) && ($this->source_height > $this->source_width)) { |
||||||||
2492 | $rotate_angle = 90; |
||||||||
2493 | } elseif (('p' === $this->ar) && ($this->source_width > $this->source_height)) { |
||||||||
2494 | $rotate_angle = 90; |
||||||||
2495 | } elseif (('P' === $this->ar) && ($this->source_width > $this->source_height)) { |
||||||||
2496 | $rotate_angle = 270; |
||||||||
2497 | } |
||||||||
2498 | } |
||||||||
2499 | if ($rotate_angle % 90) { |
||||||||
2500 | $this->is_alpha = true; |
||||||||
2501 | } |
||||||||
2502 | phpthumb_filters::ImprovedImageRotate($this->gdimg_source, $rotate_angle, $this->config_background_hexcolor, $this->bg, $this); |
||||||||
2503 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
2504 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
2505 | } |
||||||||
2506 | |||||||||
2507 | return true; |
||||||||
2508 | } |
||||||||
2509 | |||||||||
2510 | /** |
||||||||
2511 | * @return bool |
||||||||
2512 | */ |
||||||||
2513 | public function FixedAspectRatio() |
||||||||
2514 | { |
||||||||
2515 | // optional fixed-dimension images (regardless of aspect ratio) |
||||||||
2516 | |||||||||
2517 | if (!$this->far) { |
||||||||
2518 | // do nothing |
||||||||
2519 | return true; |
||||||||
2520 | } |
||||||||
2521 | |||||||||
2522 | if (!$this->w || !$this->h) { |
||||||||
2523 | return false; |
||||||||
2524 | } |
||||||||
2525 | $this->thumbnail_width = $this->w; |
||||||||
2526 | $this->thumbnail_height = $this->h; |
||||||||
2527 | $this->is_alpha = true; |
||||||||
2528 | if ($this->thumbnail_image_width >= $this->thumbnail_width) { |
||||||||
2529 | $aspectratio = $this->thumbnail_image_height / $this->thumbnail_image_width; |
||||||||
2530 | if ($this->w) { |
||||||||
2531 | $this->thumbnail_image_height = round($this->thumbnail_image_width * $aspectratio); |
||||||||
2532 | $this->thumbnail_height = ($this->h ?: $this->thumbnail_image_height); |
||||||||
2533 | } elseif ($this->thumbnail_image_height < $this->thumbnail_height) { |
||||||||
2534 | $this->thumbnail_image_height = $this->thumbnail_height; |
||||||||
2535 | $this->thumbnail_image_width = round($this->thumbnail_image_height / $aspectratio); |
||||||||
2536 | } |
||||||||
2537 | } else { |
||||||||
2538 | $aspectratio = $this->thumbnail_image_width / $this->thumbnail_image_height; |
||||||||
2539 | if ($this->h) { |
||||||||
2540 | $this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio); |
||||||||
2541 | } elseif ($this->thumbnail_image_width < $this->thumbnail_width) { |
||||||||
2542 | $this->thumbnail_image_width = $this->thumbnail_width; |
||||||||
2543 | $this->thumbnail_image_height = round($this->thumbnail_image_width / $aspectratio); |
||||||||
2544 | } |
||||||||
2545 | } |
||||||||
2546 | |||||||||
2547 | return true; |
||||||||
2548 | } |
||||||||
2549 | |||||||||
2550 | /** |
||||||||
2551 | * @param $hostname |
||||||||
2552 | * @param $allowed_domains |
||||||||
2553 | * @return mixed |
||||||||
2554 | */ |
||||||||
2555 | public function OffsiteDomainIsAllowed($hostname, $allowed_domains) |
||||||||
2556 | { |
||||||||
2557 | static $domain_is_allowed = []; |
||||||||
2558 | $hostname = mb_strtolower($hostname); |
||||||||
2559 | if (!isset($domain_is_allowed[$hostname])) { |
||||||||
2560 | $domain_is_allowed[$hostname] = false; |
||||||||
2561 | foreach ($allowed_domains as $valid_domain) { |
||||||||
2562 | $starpos = mb_strpos($valid_domain, '*'); |
||||||||
2563 | if (false !== $starpos) { |
||||||||
2564 | $valid_domain = mb_substr($valid_domain, $starpos + 1); |
||||||||
2565 | if (preg_match('#' . preg_quote($valid_domain) . '$#', $hostname)) { |
||||||||
2566 | $domain_is_allowed[$hostname] = true; |
||||||||
2567 | break; |
||||||||
2568 | } |
||||||||
2569 | } else { |
||||||||
2570 | if (mb_strtolower($valid_domain) === $hostname) { |
||||||||
2571 | $domain_is_allowed[$hostname] = true; |
||||||||
2572 | break; |
||||||||
2573 | } |
||||||||
2574 | } |
||||||||
2575 | } |
||||||||
2576 | } |
||||||||
2577 | |||||||||
2578 | return $domain_is_allowed[$hostname]; |
||||||||
2579 | } |
||||||||
2580 | |||||||||
2581 | /** |
||||||||
2582 | * @return bool |
||||||||
2583 | */ |
||||||||
2584 | public function AntiOffsiteLinking() |
||||||||
2585 | { |
||||||||
2586 | // Optional anti-offsite hijacking of the thumbnail script |
||||||||
2587 | $allow = true; |
||||||||
2588 | if ($allow && $this->config_nooffsitelink_enabled |
||||||||
2589 | && (@\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER') |
||||||||
2590 | || $this->config_nooffsitelink_require_refer)) { |
||||||||
2591 | $this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "' . @\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER') . '"', __FILE__, __LINE__); |
||||||||
2592 | foreach ($this->config_nooffsitelink_valid_domains as $key => $valid_domain) { |
||||||||
2593 | // $_SERVER['HTTP_HOST'] contains the port number, so strip it out here to make default configuration work |
||||||||
2594 | [$clean_domain] = explode(':', $valid_domain); |
||||||||
2595 | $this->config_nooffsitelink_valid_domains[$key] = $clean_domain; |
||||||||
2596 | } |
||||||||
2597 | $parsed_url = phpthumb_functions::ParseURLbetter(@\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER')); |
||||||||
2598 | if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) { |
||||||||
2599 | $allow = false; |
||||||||
2600 | //$this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__); |
||||||||
2601 | $this->ErrorImage('AntiOffsiteLinking() - "' . @$parsed_url['host'] . '" is NOT in $this->config_nooffsitelink_valid_domains (' . implode(';', $this->config_nooffsitelink_valid_domains) . ')'); |
||||||||
2602 | } else { |
||||||||
2603 | $this->DebugMessage('AntiOffsiteLinking() - "' . @$parsed_url['host'] . '" is in $this->config_nooffsitelink_valid_domains (' . implode(';', $this->config_nooffsitelink_valid_domains) . ')', __FILE__, __LINE__); |
||||||||
2604 | } |
||||||||
2605 | } |
||||||||
2606 | |||||||||
2607 | if ($allow && $this->config_nohotlink_enabled && preg_match('#^(f|ht)tps?\://#i', $this->src)) { |
||||||||
2608 | $parsed_url = phpthumb_functions::ParseURLbetter($this->src); |
||||||||
2609 | //if (!phpthumb_functions::CaseInsensitiveInArray(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) { |
||||||||
2610 | if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) { |
||||||||
2611 | // This domain is not allowed |
||||||||
2612 | $allow = false; |
||||||||
2613 | $this->DebugMessage('AntiOffsiteLinking() - "' . $parsed_url['host'] . '" is NOT in $this->config_nohotlink_valid_domains (' . implode(';', $this->config_nohotlink_valid_domains) . ')', __FILE__, __LINE__); |
||||||||
2614 | } else { |
||||||||
2615 | $this->DebugMessage('AntiOffsiteLinking() - "' . $parsed_url['host'] . '" is in $this->config_nohotlink_valid_domains (' . implode(';', $this->config_nohotlink_valid_domains) . ')', __FILE__, __LINE__); |
||||||||
2616 | } |
||||||||
2617 | } |
||||||||
2618 | |||||||||
2619 | if ($allow) { |
||||||||
2620 | $this->DebugMessage('AntiOffsiteLinking() says this is allowed', __FILE__, __LINE__); |
||||||||
2621 | |||||||||
2622 | return true; |
||||||||
2623 | } |
||||||||
2624 | |||||||||
2625 | if (!phpthumb_functions::IsHexColor($this->config_error_bgcolor)) { |
||||||||
2626 | return $this->ErrorImage('Invalid hex color string "' . $this->config_error_bgcolor . '" for $this->config_error_bgcolor'); |
||||||||
2627 | } |
||||||||
2628 | if (!phpthumb_functions::IsHexColor($this->config_error_textcolor)) { |
||||||||
2629 | return $this->ErrorImage('Invalid hex color string "' . $this->config_error_textcolor . '" for $this->config_error_textcolor'); |
||||||||
2630 | } |
||||||||
2631 | if ($this->config_nooffsitelink_erase_image) { |
||||||||
2632 | return $this->ErrorImage($this->config_nooffsitelink_text_message, $this->thumbnail_width, $this->thumbnail_height); |
||||||||
2633 | } |
||||||||
2634 | $this->config_nooffsitelink_watermark_src = $this->ResolveFilenameToAbsolute($this->config_nooffsitelink_watermark_src); |
||||||||
2635 | if (is_file($this->config_nooffsitelink_watermark_src)) { |
||||||||
0 ignored issues
–
show
It seems like
$this->config_nooffsitelink_watermark_src can also be of type false and null ; however, parameter $filename of is_file() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
2636 | if (!require_once __DIR__ . '/phpthumb.filters.php') { |
||||||||
2637 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__); |
||||||||
2638 | |||||||||
2639 | return false; |
||||||||
2640 | } |
||||||||
2641 | $watermark_img = $this->ImageCreateFromStringReplacement(file_get_contents($this->config_nooffsitelink_watermark_src)); |
||||||||
0 ignored issues
–
show
It seems like
$this->config_nooffsitelink_watermark_src can also be of type false and null ; however, parameter $filename of file_get_contents() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() file_get_contents($this-...sitelink_watermark_src) cannot be passed to phpthumb::ImageCreateFromStringReplacement() as the parameter $RawImageData expects a reference.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
2642 | $phpthumbFilters = new phpthumb_filters(); |
||||||||
2643 | $phpthumbFilters->phpThumbObject = &$this; |
||||||||
2644 | $opacity = 50; |
||||||||
2645 | $margin = 5; |
||||||||
2646 | $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $watermark_img, '*', $opacity, $margin); |
||||||||
2647 | imagedestroy($watermark_img); |
||||||||
2648 | unset($phpthumbFilters); |
||||||||
2649 | } else { |
||||||||
2650 | $nohotlink_text_array = explode("\n", wordwrap($this->config_nooffsitelink_text_message, floor($this->thumbnail_width / imagefontwidth($this->config_error_fontsize)), "\n")); |
||||||||
0 ignored issues
–
show
floor($this->thumbnail_w...config_error_fontsize)) of type double is incompatible with the type integer expected by parameter $width of wordwrap() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
2651 | $nohotlink_text_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_error_textcolor); |
||||||||
2652 | |||||||||
2653 | $topoffset = round(($this->thumbnail_height - (count($nohotlink_text_array) * imagefontheight($this->config_error_fontsize))) / 2); |
||||||||
2654 | |||||||||
2655 | $rowcounter = 0; |
||||||||
2656 | $this->DebugMessage('AntiOffsiteLinking() writing ' . count($nohotlink_text_array) . ' lines of text "' . $this->config_nooffsitelink_text_message . '" (in #' . $this->config_error_textcolor . ') on top of image', __FILE__, __LINE__); |
||||||||
2657 | foreach ($nohotlink_text_array as $textline) { |
||||||||
2658 | $leftoffset = max(0, round(($this->thumbnail_width - (mb_strlen($textline) * imagefontwidth($this->config_error_fontsize))) / 2)); |
||||||||
2659 | imagestring($this->gdimg_output, $this->config_error_fontsize, $leftoffset, $topoffset + ($rowcounter++ * imagefontheight($this->config_error_fontsize)), $textline, $nohotlink_text_color); |
||||||||
2660 | } |
||||||||
2661 | } |
||||||||
2662 | |||||||||
2663 | return true; |
||||||||
2664 | } |
||||||||
2665 | |||||||||
2666 | /** |
||||||||
2667 | * @return bool |
||||||||
2668 | */ |
||||||||
2669 | public function AlphaChannelFlatten() |
||||||||
2670 | { |
||||||||
2671 | if (!$this->is_alpha) { |
||||||||
2672 | // image doesn't have alpha transparency, no need to flatten |
||||||||
2673 | $this->DebugMessage('skipping AlphaChannelFlatten() because !$this->is_alpha', __FILE__, __LINE__); |
||||||||
2674 | |||||||||
2675 | return false; |
||||||||
2676 | } |
||||||||
2677 | switch ($this->thumbnailFormat) { |
||||||||
2678 | case 'png': |
||||||||
2679 | case 'ico': |
||||||||
2680 | // image has alpha transparency, but output as PNG or ICO which can handle it |
||||||||
2681 | $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "' . $this->thumbnailFormat . '")', __FILE__, __LINE__); |
||||||||
2682 | |||||||||
2683 | return false; |
||||||||
2684 | break; |
||||||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||||||
2685 | case 'gif': |
||||||||
2686 | // image has alpha transparency, but output as GIF which can handle only single-color transparency |
||||||||
2687 | $CurrentImageColorTransparent = imagecolortransparent($this->gdimg_output); |
||||||||
2688 | if (-1 == $CurrentImageColorTransparent) { |
||||||||
2689 | // no transparent color defined |
||||||||
2690 | |||||||||
2691 | if (phpthumb_functions::gd_version() < 2.0) { |
||||||||
2692 | $this->DebugMessage('AlphaChannelFlatten() failed because GD version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2693 | |||||||||
2694 | return false; |
||||||||
2695 | } |
||||||||
2696 | |||||||||
2697 | if ($img_alpha_mixdown_dither = @imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) { |
||||||||
2698 | $dither_color = []; |
||||||||
2699 | for ($i = 0; $i <= 255; ++$i) { |
||||||||
2700 | $dither_color[$i] = imagecolorallocate($img_alpha_mixdown_dither, $i, $i, $i); |
||||||||
2701 | } |
||||||||
2702 | |||||||||
2703 | // scan through current truecolor image copy alpha channel to temp image as grayscale |
||||||||
2704 | for ($x = 0; $x < $this->thumbnail_width; $x++) { |
||||||||
2705 | for ($y = 0; $y < $this->thumbnail_height; $y++) { |
||||||||
2706 | $PixelColor = phpthumb_functions::GetPixelColor($this->gdimg_output, $x, $y); |
||||||||
2707 | imagesetpixel($img_alpha_mixdown_dither, $x, $y, $dither_color[$PixelColor['alpha'] * 2]); |
||||||||
2708 | } |
||||||||
2709 | } |
||||||||
2710 | |||||||||
2711 | // dither alpha channel grayscale version down to 2 colors |
||||||||
2712 | imagetruecolortopalette($img_alpha_mixdown_dither, true, 2); |
||||||||
2713 | |||||||||
2714 | // reduce color palette to 256-1 colors (leave one palette position for transparent color) |
||||||||
2715 | imagetruecolortopalette($this->gdimg_output, true, 255); |
||||||||
2716 | |||||||||
2717 | // allocate a new color for transparent color index |
||||||||
2718 | $TransparentColor = imagecolorallocate($this->gdimg_output, 1, 254, 253); |
||||||||
2719 | imagecolortransparent($this->gdimg_output, $TransparentColor); |
||||||||
2720 | |||||||||
2721 | // scan through alpha channel image and note pixels with >50% transparency |
||||||||
2722 | for ($x = 0; $x < $this->thumbnail_width; $x++) { |
||||||||
2723 | for ($y = 0; $y < $this->thumbnail_height; $y++) { |
||||||||
2724 | $AlphaChannelPixel = phpthumb_functions::GetPixelColor($img_alpha_mixdown_dither, $x, $y); |
||||||||
2725 | if ($AlphaChannelPixel['red'] > 127) { |
||||||||
2726 | imagesetpixel($this->gdimg_output, $x, $y, $TransparentColor); |
||||||||
2727 | } |
||||||||
2728 | } |
||||||||
2729 | } |
||||||||
2730 | imagedestroy($img_alpha_mixdown_dither); |
||||||||
2731 | |||||||||
2732 | $this->DebugMessage('AlphaChannelFlatten() set image to 255+1 colors with transparency for GIF output', __FILE__, __LINE__); |
||||||||
2733 | |||||||||
2734 | return true; |
||||||||
2735 | } |
||||||||
2736 | $this->DebugMessage('AlphaChannelFlatten() failed imagecreate(' . imagesx($this->gdimg_output) . ', ' . imagesy($this->gdimg_output) . ')', __FILE__, __LINE__); |
||||||||
2737 | |||||||||
2738 | return false; |
||||||||
2739 | } |
||||||||
2740 | // a single transparent color already defined, leave as-is |
||||||||
2741 | $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "' . $this->thumbnailFormat . '") and imagecolortransparent() returned "' . $CurrentImageColorTransparent . '"', __FILE__, __LINE__); |
||||||||
2742 | |||||||||
2743 | return true; |
||||||||
2744 | break; |
||||||||
2745 | } |
||||||||
2746 | $this->DebugMessage('continuing AlphaChannelFlatten() for output format "' . $this->thumbnailFormat . '"', __FILE__, __LINE__); |
||||||||
2747 | // image has alpha transparency, and is being output in a format that doesn't support it -- flatten |
||||||||
2748 | if ($gdimg_flatten_temp = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height)) { |
||||||||
2749 | $this->config_background_hexcolor = ($this->bg ?: $this->config_background_hexcolor); |
||||||||
2750 | if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) { |
||||||||
2751 | return $this->ErrorImage('Invalid hex color string "' . $this->config_background_hexcolor . '" for parameter "bg"'); |
||||||||
2752 | } |
||||||||
2753 | $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor); |
||||||||
2754 | imagefilledrectangle($gdimg_flatten_temp, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color); |
||||||||
2755 | imagecopy($gdimg_flatten_temp, $this->gdimg_output, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height); |
||||||||
2756 | |||||||||
2757 | imagealphablending($this->gdimg_output, true); |
||||||||
2758 | imagesavealpha($this->gdimg_output, false); |
||||||||
2759 | imagecolortransparent($this->gdimg_output, -1); |
||||||||
2760 | imagecopy($this->gdimg_output, $gdimg_flatten_temp, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height); |
||||||||
2761 | |||||||||
2762 | imagedestroy($gdimg_flatten_temp); |
||||||||
2763 | |||||||||
2764 | return true; |
||||||||
2765 | } |
||||||||
2766 | $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__); |
||||||||
2767 | |||||||||
2768 | return false; |
||||||||
2769 | } |
||||||||
2770 | |||||||||
2771 | /** |
||||||||
2772 | * @return bool |
||||||||
2773 | */ |
||||||||
2774 | public function ApplyFilters() |
||||||||
2775 | { |
||||||||
2776 | if ($this->fltr && is_array($this->fltr)) { |
||||||||
0 ignored issues
–
show
The expression
$this->fltr of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||||||
2777 | if (!require_once __DIR__ . '/phpthumb.filters.php') { |
||||||||
2778 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.filters.php" which is required for applying filters (' . implode(';', $this->fltr) . ')', __FILE__, __LINE__); |
||||||||
2779 | |||||||||
2780 | return false; |
||||||||
2781 | } |
||||||||
2782 | $phpthumbFilters = new phpthumb_filters(); |
||||||||
2783 | $phpthumbFilters->phpThumbObject = &$this; |
||||||||
2784 | foreach ($this->fltr as $filtercommand) { |
||||||||
2785 | @list($command, $parameter) = explode('|', $filtercommand, 2); |
||||||||
2786 | $this->DebugMessage('Attempting to process filter command "' . $command . '(' . $parameter . ')"', __FILE__, __LINE__); |
||||||||
2787 | switch ($command) { |
||||||||
2788 | case 'brit': // Brightness |
||||||||
2789 | $phpthumbFilters->Brightness($this->gdimg_output, $parameter); |
||||||||
2790 | break; |
||||||||
2791 | case 'cont': // Contrast |
||||||||
2792 | $phpthumbFilters->Contrast($this->gdimg_output, $parameter); |
||||||||
2793 | break; |
||||||||
2794 | case 'ds': // Desaturation |
||||||||
2795 | $phpthumbFilters->Desaturate($this->gdimg_output, $parameter, ''); |
||||||||
2796 | break; |
||||||||
2797 | case 'sat': // Saturation |
||||||||
2798 | $phpthumbFilters->Saturation($this->gdimg_output, $parameter, ''); |
||||||||
2799 | break; |
||||||||
2800 | case 'gray': // Grayscale |
||||||||
2801 | $phpthumbFilters->Grayscale($this->gdimg_output); |
||||||||
2802 | break; |
||||||||
2803 | case 'clr': // Colorize |
||||||||
2804 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2805 | $this->DebugMessage('Skipping Colorize() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2806 | break; |
||||||||
2807 | } |
||||||||
2808 | @list($amount, $color) = explode('|', $parameter, 2); |
||||||||
2809 | $phpthumbFilters->Colorize($this->gdimg_output, $amount, $color); |
||||||||
2810 | break; |
||||||||
2811 | case 'sep': // Sepia |
||||||||
2812 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2813 | $this->DebugMessage('Skipping Sepia() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2814 | break; |
||||||||
2815 | } |
||||||||
2816 | @list($amount, $color) = explode('|', $parameter, 2); |
||||||||
2817 | $phpthumbFilters->Sepia($this->gdimg_output, $amount, $color); |
||||||||
2818 | break; |
||||||||
2819 | case 'gam': // Gamma correction |
||||||||
2820 | $phpthumbFilters->Gamma($this->gdimg_output, $parameter); |
||||||||
2821 | break; |
||||||||
2822 | case 'neg': // Negative colors |
||||||||
2823 | $phpthumbFilters->Negative($this->gdimg_output); |
||||||||
2824 | break; |
||||||||
2825 | case 'th': // Threshold |
||||||||
2826 | $phpthumbFilters->Threshold($this->gdimg_output, $parameter); |
||||||||
2827 | break; |
||||||||
2828 | case 'rcd': // ReduceColorDepth |
||||||||
2829 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2830 | $this->DebugMessage('Skipping ReduceColorDepth() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2831 | break; |
||||||||
2832 | } |
||||||||
2833 | @list($colors, $dither) = explode('|', $parameter, 2); |
||||||||
2834 | $colors = ($colors ? (int)$colors : 256); |
||||||||
2835 | $dither = ((mb_strlen($dither) > 0) ? (bool)$dither : true); |
||||||||
2836 | $phpthumbFilters->ReduceColorDepth($this->gdimg_output, $colors, $dither); |
||||||||
2837 | break; |
||||||||
2838 | case 'flip': // Flip |
||||||||
2839 | $phpthumbFilters->Flip($this->gdimg_output, false !== mb_strpos(mb_strtolower($parameter), 'x'), false !== mb_strpos(mb_strtolower($parameter), 'y')); |
||||||||
2840 | break; |
||||||||
2841 | case 'edge': // EdgeDetect |
||||||||
2842 | $phpthumbFilters->EdgeDetect($this->gdimg_output); |
||||||||
2843 | break; |
||||||||
2844 | case 'emb': // Emboss |
||||||||
2845 | $phpthumbFilters->Emboss($this->gdimg_output); |
||||||||
2846 | break; |
||||||||
2847 | case 'bvl': // Bevel |
||||||||
2848 | @list($width, $color1, $color2) = explode('|', $parameter, 3); |
||||||||
2849 | $phpthumbFilters->Bevel($this->gdimg_output, $width, $color1, $color2); |
||||||||
2850 | break; |
||||||||
2851 | case 'lvl': // autoLevels |
||||||||
2852 | @list($band, $method, $threshold) = explode('|', $parameter, 3); |
||||||||
2853 | $band = ($band ? preg_replace('#[^RGBA\\*]#', '', mb_strtoupper($band)) : '*'); |
||||||||
2854 | $method = ((mb_strlen($method) > 0) ? (int)$method : 2); |
||||||||
2855 | $threshold = ((mb_strlen($threshold) > 0) ? (float)$threshold : 0.1); |
||||||||
2856 | |||||||||
2857 | $phpthumbFilters->HistogramStretch($this->gdimg_output, $band, $method, $threshold); |
||||||||
2858 | break; |
||||||||
2859 | case 'wb': // WhiteBalance |
||||||||
2860 | $phpthumbFilters->WhiteBalance($this->gdimg_output, $parameter); |
||||||||
2861 | break; |
||||||||
2862 | case 'hist': // Histogram overlay |
||||||||
2863 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2864 | $this->DebugMessage('Skipping HistogramOverlay() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2865 | break; |
||||||||
2866 | } |
||||||||
2867 | @list($bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y) = explode('|', $parameter, 8); |
||||||||
2868 | $bands = ($bands ?: '*'); |
||||||||
2869 | $colors = ($colors ?: ''); |
||||||||
2870 | $width = ($width ?: 0.25); |
||||||||
2871 | $height = ($height ?: 0.25); |
||||||||
2872 | $alignment = ($alignment ?: 'BR'); |
||||||||
2873 | $opacity = ($opacity ?: 50); |
||||||||
2874 | $margin_x = ($margin_x ?: 5); |
||||||||
2875 | // $margin_y -- it wasn't forgotten, let the value always pass unchanged |
||||||||
2876 | $phpthumbFilters->HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y); |
||||||||
2877 | break; |
||||||||
2878 | case 'fram': // Frame |
||||||||
2879 | @list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter, 5); |
||||||||
2880 | $phpthumbFilters->Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2); |
||||||||
2881 | break; |
||||||||
2882 | case 'drop': // DropShadow |
||||||||
2883 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2884 | $this->DebugMessage('Skipping DropShadow() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2885 | |||||||||
2886 | return false; |
||||||||
2887 | } |
||||||||
2888 | $this->is_alpha = true; |
||||||||
2889 | @list($distance, $width, $color, $angle, $fade) = explode('|', $parameter, 5); |
||||||||
2890 | $phpthumbFilters->DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade); |
||||||||
2891 | break; |
||||||||
2892 | case 'mask': // Mask cropping |
||||||||
2893 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2894 | $this->DebugMessage('Skipping Mask() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2895 | |||||||||
2896 | return false; |
||||||||
2897 | } |
||||||||
2898 | @list($mask_filename, $invert) = explode('|', $parameter, 2); |
||||||||
2899 | $mask_filename = $this->ResolveFilenameToAbsolute($mask_filename); |
||||||||
2900 | if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) { |
||||||||
0 ignored issues
–
show
It seems like
$mask_filename can also be of type false and null ; however, parameter $filename of is_readable() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$mask_filename can also be of type false and null ; however, parameter $filename of fopen() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
2901 | $MaskImageData = ''; |
||||||||
2902 | do { |
||||||||
2903 | $buffer = fread($fp_mask, 8192); |
||||||||
2904 | $MaskImageData .= $buffer; |
||||||||
2905 | } while (mb_strlen($buffer) > 0); |
||||||||
2906 | fclose($fp_mask); |
||||||||
2907 | if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) { |
||||||||
2908 | if ($invert |
||||||||
2909 | && phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') |
||||||||
2910 | && phpthumb_functions::gd_is_bundled()) { |
||||||||
2911 | imagefilter($gdimg_mask, IMG_FILTER_NEGATE); |
||||||||
2912 | } |
||||||||
2913 | $this->is_alpha = true; |
||||||||
2914 | $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output); |
||||||||
2915 | imagedestroy($gdimg_mask); |
||||||||
2916 | } else { |
||||||||
2917 | $this->DebugMessage('ImageCreateFromStringReplacement() failed for "' . $mask_filename . '"', __FILE__, __LINE__); |
||||||||
2918 | } |
||||||||
2919 | } else { |
||||||||
2920 | $this->DebugMessage('Cannot open mask file "' . $mask_filename . '"', __FILE__, __LINE__); |
||||||||
2921 | } |
||||||||
2922 | break; |
||||||||
2923 | case 'elip': // Ellipse cropping |
||||||||
2924 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2925 | $this->DebugMessage('Skipping Ellipse() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2926 | |||||||||
2927 | return false; |
||||||||
2928 | } |
||||||||
2929 | $this->is_alpha = true; |
||||||||
2930 | $phpthumbFilters->Ellipse($this->gdimg_output); |
||||||||
2931 | break; |
||||||||
2932 | case 'ric': // RoundedImageCorners |
||||||||
2933 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
2934 | $this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
2935 | |||||||||
2936 | return false; |
||||||||
2937 | } |
||||||||
2938 | @list($radius_x, $radius_y) = explode('|', $parameter, 2); |
||||||||
2939 | if (($radius_x < 1) || ($radius_y < 1)) { |
||||||||
2940 | $this->DebugMessage('Skipping RoundedImageCorners(' . $radius_x . ', ' . $radius_y . ') because x/y radius is less than 1', __FILE__, __LINE__); |
||||||||
2941 | break; |
||||||||
2942 | } |
||||||||
2943 | $this->is_alpha = true; |
||||||||
2944 | $phpthumbFilters->RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y); |
||||||||
2945 | break; |
||||||||
2946 | case 'crop': // Crop |
||||||||
2947 | @list($left, $right, $top, $bottom) = explode('|', $parameter, 4); |
||||||||
2948 | $phpthumbFilters->Crop($this->gdimg_output, $left, $right, $top, $bottom); |
||||||||
2949 | break; |
||||||||
2950 | case 'bord': // Border |
||||||||
2951 | @list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter, 4); |
||||||||
2952 | $this->is_alpha = true; |
||||||||
2953 | $phpthumbFilters->ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border); |
||||||||
2954 | break; |
||||||||
2955 | case 'over': // Overlay |
||||||||
2956 | @list($filename, $underlay, $margin, $opacity) = explode('|', $parameter, 4); |
||||||||
2957 | $underlay = ($underlay ?: false); |
||||||||
2958 | $margin = ((mb_strlen($margin) > 0) ? $margin : ($underlay ? 0.1 : 0.0)); |
||||||||
2959 | $opacity = ((mb_strlen($opacity) > 0) ? $opacity : 100); |
||||||||
2960 | if (($margin > 0) && ($margin < 1)) { |
||||||||
2961 | $margin = min(0.499, $margin); |
||||||||
2962 | } elseif (($margin > -1) && ($margin < 0)) { |
||||||||
2963 | $margin = max(-0.499, $margin); |
||||||||
2964 | } |
||||||||
2965 | |||||||||
2966 | $filename = $this->ResolveFilenameToAbsolute($filename); |
||||||||
2967 | if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) { |
||||||||
2968 | $WatermarkImageData = ''; |
||||||||
2969 | do { |
||||||||
2970 | $buffer = fread($fp_watermark, 8192); |
||||||||
2971 | $WatermarkImageData .= $buffer; |
||||||||
2972 | } while (mb_strlen($buffer) > 0); |
||||||||
2973 | fclose($fp_watermark); |
||||||||
2974 | if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) { |
||||||||
2975 | if (($margin > 0) && ($margin < 1)) { |
||||||||
2976 | $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * (imagesx($this->gdimg_output) * $margin))); |
||||||||
2977 | $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * (imagesy($this->gdimg_output) * $margin))); |
||||||||
2978 | } else { |
||||||||
2979 | $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * $margin)); |
||||||||
2980 | $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * $margin)); |
||||||||
2981 | } |
||||||||
2982 | |||||||||
2983 | if ($underlay) { |
||||||||
2984 | if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) { |
||||||||
2985 | imagealphablending($img_watermark_resized, false); |
||||||||
2986 | imagesavealpha($img_watermark_resized, true); |
||||||||
2987 | $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark)); |
||||||||
2988 | if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) { |
||||||||
2989 | imagealphablending($img_source_resized, false); |
||||||||
2990 | imagesavealpha($img_source_resized, true); |
||||||||
2991 | $this->ImageResizeFunction($img_source_resized, $this->gdimg_output, 0, 0, 0, 0, imagesx($img_source_resized), imagesy($img_source_resized), imagesx($this->gdimg_output), imagesy($this->gdimg_output)); |
||||||||
2992 | $phpthumbFilters->WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin); |
||||||||
2993 | imagecopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output)); |
||||||||
2994 | } else { |
||||||||
2995 | $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . $resized_x . ', ' . $resized_y . ')', __FILE__, __LINE__); |
||||||||
2996 | } |
||||||||
2997 | imagedestroy($img_watermark_resized); |
||||||||
2998 | } else { |
||||||||
2999 | $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . imagesx($this->gdimg_output) . ', ' . imagesy($this->gdimg_output) . ')', __FILE__, __LINE__); |
||||||||
3000 | } |
||||||||
3001 | } else { // overlay |
||||||||
3002 | if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) { |
||||||||
3003 | imagealphablending($img_watermark_resized, false); |
||||||||
3004 | imagesavealpha($img_watermark_resized, true); |
||||||||
3005 | $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark)); |
||||||||
3006 | $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin); |
||||||||
3007 | imagedestroy($img_watermark_resized); |
||||||||
3008 | } else { |
||||||||
3009 | $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . $resized_x . ', ' . $resized_y . ')', __FILE__, __LINE__); |
||||||||
3010 | } |
||||||||
3011 | } |
||||||||
3012 | imagedestroy($img_watermark); |
||||||||
3013 | } else { |
||||||||
3014 | $this->DebugMessage('ImageCreateFromStringReplacement() failed for "' . $filename . '"', __FILE__, __LINE__); |
||||||||
3015 | } |
||||||||
3016 | } else { |
||||||||
3017 | $this->DebugMessage('Cannot open overlay file "' . $filename . '"', __FILE__, __LINE__); |
||||||||
3018 | } |
||||||||
3019 | break; |
||||||||
3020 | case 'wmi': // WaterMarkImage |
||||||||
3021 | @list($filename, $alignment, $opacity, $margin['x'], $margin['y'], $rotate_angle) = explode('|', $parameter, 6); |
||||||||
3022 | // $margin can be pixel margin or percent margin if $alignment is text, or max width/height if $alignment is position like "50x75" |
||||||||
3023 | $alignment = ($alignment ?: 'BR'); |
||||||||
3024 | $opacity = (mb_strlen($opacity) ? (int)$opacity : 50); |
||||||||
3025 | $rotate_angle = (mb_strlen($rotate_angle) ? (int)$rotate_angle : 0); |
||||||||
3026 | if (!preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) { |
||||||||
3027 | $margins = ['x', 'y']; |
||||||||
3028 | foreach ($margins as $xy) { |
||||||||
3029 | $margin[$xy] = (mb_strlen($margin[$xy]) ? $margin[$xy] : 5); |
||||||||
3030 | if (($margin[$xy] > 0) && ($margin[$xy] < 1)) { |
||||||||
3031 | $margin[$xy] = min(0.499, $margin[$xy]); |
||||||||
3032 | } elseif (($margin[$xy] > -1) && ($margin[$xy] < 0)) { |
||||||||
3033 | $margin[$xy] = max(-0.499, $margin[$xy]); |
||||||||
3034 | } |
||||||||
3035 | } |
||||||||
3036 | } |
||||||||
3037 | |||||||||
3038 | $filename = $this->ResolveFilenameToAbsolute($filename); |
||||||||
3039 | if (@is_readable($filename)) { |
||||||||
3040 | if ($img_watermark = $this->ImageCreateFromFilename($filename)) { |
||||||||
3041 | if (0 !== $rotate_angle) { |
||||||||
3042 | $phpthumbFilters->ImprovedImageRotate($img_watermark, $rotate_angle, 'FFFFFF', null, $this); |
||||||||
3043 | } |
||||||||
3044 | if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) { |
||||||||
3045 | $watermark_max_width = ($margin['x'] ?: imagesx($img_watermark)); |
||||||||
3046 | $watermark_max_height = ($margin['y'] ?: imagesy($img_watermark)); |
||||||||
3047 | $scale = phpthumb_functions::ScaleToFitInBox(imagesx($img_watermark), imagesy($img_watermark), $watermark_max_width, $watermark_max_height, true, true); |
||||||||
3048 | $this->DebugMessage('Scaling watermark by a factor of ' . number_format($scale, 4), __FILE__, __LINE__); |
||||||||
3049 | if (($scale > 1) || ($scale < 1)) { |
||||||||
3050 | if ($img_watermark2 = phpthumb_functions::ImageCreateFunction($scale * imagesx($img_watermark), $scale * imagesy($img_watermark))) { |
||||||||
3051 | imagealphablending($img_watermark2, false); |
||||||||
3052 | imagesavealpha($img_watermark2, true); |
||||||||
3053 | $this->ImageResizeFunction($img_watermark2, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark2), imagesy($img_watermark2), imagesx($img_watermark), imagesy($img_watermark)); |
||||||||
3054 | $img_watermark = $img_watermark2; |
||||||||
3055 | } else { |
||||||||
3056 | $this->DebugMessage('ImageCreateFunction(' . ($scale * imagesx($img_watermark)) . ', ' . ($scale * imagesx($img_watermark)) . ') failed', __FILE__, __LINE__); |
||||||||
3057 | } |
||||||||
3058 | } |
||||||||
3059 | $watermark_dest_x = round($matches[1] - (imagesx($img_watermark) / 2)); |
||||||||
3060 | $watermark_dest_y = round($matches[2] - (imagesy($img_watermark) / 2)); |
||||||||
3061 | $alignment = $watermark_dest_x . 'x' . $watermark_dest_y; |
||||||||
3062 | } |
||||||||
3063 | $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin['x'], $margin['y']); |
||||||||
3064 | imagedestroy($img_watermark); |
||||||||
3065 | if (isset($img_watermark2) && is_resource($img_watermark2)) { |
||||||||
3066 | imagedestroy($img_watermark2); |
||||||||
3067 | } |
||||||||
3068 | } else { |
||||||||
3069 | $this->DebugMessage('ImageCreateFromFilename() failed for "' . $filename . '"', __FILE__, __LINE__); |
||||||||
3070 | } |
||||||||
3071 | } else { |
||||||||
3072 | $this->DebugMessage('!is_readable(' . $filename . ')', __FILE__, __LINE__); |
||||||||
3073 | } |
||||||||
3074 | break; |
||||||||
3075 | case 'wmt': // WaterMarkText |
||||||||
3076 | @list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend) = explode('|', $parameter, 11); |
||||||||
3077 | $text = ($text ?: ''); |
||||||||
3078 | $size = ($size ?: 3); |
||||||||
3079 | $alignment = ($alignment ?: 'BR'); |
||||||||
3080 | $hex_color = ($hex_color ?: '000000'); |
||||||||
3081 | $ttffont = ($ttffont ?: ''); |
||||||||
3082 | $opacity = (mb_strlen($opacity) ? $opacity : 50); |
||||||||
3083 | $margin = (mb_strlen($margin) ? $margin : 5); |
||||||||
3084 | $angle = (mb_strlen($angle) ? $angle : 0); |
||||||||
3085 | $bg_color = ($bg_color ?: false); |
||||||||
3086 | $bg_opacity = ($bg_opacity ?: 0); |
||||||||
3087 | $fillextend = ($fillextend ?: ''); |
||||||||
3088 | |||||||||
3089 | if (basename($ttffont) == $ttffont) { |
||||||||
3090 | $ttffont = $this->realPathSafe($this->config_ttf_directory . DIRECTORY_SEPARATOR . $ttffont); |
||||||||
3091 | } else { |
||||||||
3092 | $ttffont = $this->ResolveFilenameToAbsolute($ttffont); |
||||||||
3093 | } |
||||||||
3094 | $phpthumbFilters->WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend); |
||||||||
3095 | break; |
||||||||
3096 | case 'blur': // Blur |
||||||||
3097 | @list($radius) = explode('|', $parameter, 1); |
||||||||
3098 | $radius = ($radius ?: 1); |
||||||||
3099 | if (phpthumb_functions::gd_version() >= 2) { |
||||||||
3100 | $phpthumbFilters->Blur($this->gdimg_output, $radius); |
||||||||
3101 | } else { |
||||||||
3102 | $this->DebugMessage('Skipping Blur() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
3103 | } |
||||||||
3104 | break; |
||||||||
3105 | case 'gblr': // Gaussian Blur |
||||||||
3106 | $phpthumbFilters->BlurGaussian($this->gdimg_output); |
||||||||
3107 | break; |
||||||||
3108 | case 'sblr': // Selective Blur |
||||||||
3109 | $phpthumbFilters->BlurSelective($this->gdimg_output); |
||||||||
3110 | break; |
||||||||
3111 | case 'mean': // MeanRemoval blur |
||||||||
3112 | $phpthumbFilters->MeanRemoval($this->gdimg_output); |
||||||||
3113 | break; |
||||||||
3114 | case 'smth': // Smooth blur |
||||||||
3115 | $phpthumbFilters->Smooth($this->gdimg_output, $parameter); |
||||||||
3116 | break; |
||||||||
3117 | case 'usm': // UnSharpMask sharpening |
||||||||
3118 | @list($amount, $radius, $threshold) = explode('|', $parameter, 3); |
||||||||
3119 | $amount = ($amount ?: 80); |
||||||||
3120 | $radius = ($radius ?: 0.5); |
||||||||
3121 | $threshold = (mb_strlen($threshold) ? $threshold : 3); |
||||||||
3122 | if (phpthumb_functions::gd_version() >= 2.0) { |
||||||||
3123 | ob_start(); |
||||||||
3124 | if (!@require_once __DIR__ . '/phpthumb.unsharp.php') { |
||||||||
3125 | $include_error = ob_get_contents(); |
||||||||
3126 | if ($include_error) { |
||||||||
3127 | $this->DebugMessage('include_once("' . __DIR__ . '/phpthumb.unsharp.php") generated message: "' . $include_error . '"', __FILE__, __LINE__); |
||||||||
3128 | } |
||||||||
3129 | $this->DebugMessage('Error including "' . __DIR__ . '/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__); |
||||||||
3130 | ob_end_clean(); |
||||||||
3131 | |||||||||
3132 | return false; |
||||||||
3133 | } |
||||||||
3134 | ob_end_clean(); |
||||||||
3135 | phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold); |
||||||||
3136 | } else { |
||||||||
3137 | $this->DebugMessage('Skipping unsharp mask because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
3138 | |||||||||
3139 | return false; |
||||||||
3140 | } |
||||||||
3141 | break; |
||||||||
3142 | case 'size': // Resize |
||||||||
3143 | @list($newwidth, $newheight, $stretch) = explode('|', $parameter); |
||||||||
3144 | $newwidth = (!$newwidth ? imagesx($this->gdimg_output) : ((($newwidth > 0) |
||||||||
3145 | && ($newwidth < 1)) ? round($newwidth * imagesx($this->gdimg_output)) : round($newwidth))); |
||||||||
0 ignored issues
–
show
$newwidth of type string is incompatible with the type double|integer expected by parameter $num of round() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3146 | $newheight = (!$newheight ? imagesy($this->gdimg_output) : ((($newheight > 0) |
||||||||
3147 | && ($newheight < 1)) ? round($newheight * imagesy($this->gdimg_output)) : round($newheight))); |
||||||||
3148 | $stretch = ($stretch ? true : false); |
||||||||
3149 | if ($stretch) { |
||||||||
3150 | $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth, $newwidth, true, true); |
||||||||
3151 | $scale_y = phpthumb_functions::ScaleToFitInBox(imagesy($this->gdimg_output), imagesy($this->gdimg_output), $newheight, $newheight, true, true); |
||||||||
3152 | } else { |
||||||||
3153 | $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesy($this->gdimg_output), $newwidth, $newheight, true, true); |
||||||||
3154 | $scale_y = $scale_x; |
||||||||
3155 | } |
||||||||
3156 | $this->DebugMessage('Scaling watermark (' . ($stretch ? 'with' : 'without') . ' stretch) by a factor of "' . number_format($scale_x, 4) . ' x ' . number_format($scale_y, 4) . '"', __FILE__, __LINE__); |
||||||||
3157 | if (($scale_x > 1) || ($scale_x < 1) || ($scale_y > 1) || ($scale_y < 1)) { |
||||||||
3158 | if ($img_temp = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) { |
||||||||
3159 | imagecopy($img_temp, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output)); |
||||||||
3160 | if ($this->gdimg_output = phpthumb_functions::ImageCreateFunction($scale_x * imagesx($img_temp), $scale_y * imagesy($img_temp))) { |
||||||||
3161 | imagealphablending($this->gdimg_output, false); |
||||||||
3162 | imagesavealpha($this->gdimg_output, true); |
||||||||
3163 | $this->ImageResizeFunction($this->gdimg_output, $img_temp, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output), imagesx($img_temp), imagesy($img_temp)); |
||||||||
3164 | } else { |
||||||||
3165 | $this->DebugMessage('ImageCreateFunction(' . ($scale_x * imagesx($img_temp)) . ', ' . ($scale_y * imagesy($img_temp)) . ') failed', __FILE__, __LINE__); |
||||||||
3166 | } |
||||||||
3167 | imagedestroy($img_temp); |
||||||||
3168 | } else { |
||||||||
3169 | $this->DebugMessage('ImageCreateFunction(' . imagesx($this->gdimg_output) . ', ' . imagesy($this->gdimg_output) . ') failed', __FILE__, __LINE__); |
||||||||
3170 | } |
||||||||
3171 | } |
||||||||
3172 | break; |
||||||||
3173 | case 'rot': // ROTate |
||||||||
3174 | @list($angle, $bgcolor) = explode('|', $parameter, 2); |
||||||||
3175 | $phpthumbFilters->ImprovedImageRotate($this->gdimg_output, $angle, $bgcolor, null, $this); |
||||||||
3176 | break; |
||||||||
3177 | case 'stc': // Source Transparent Color |
||||||||
3178 | @list($hexcolor, $min_limit, $max_limit) = explode('|', $parameter, 3); |
||||||||
3179 | if (!phpthumb_functions::IsHexColor($hexcolor)) { |
||||||||
3180 | $this->DebugMessage('Skipping SourceTransparentColor hex color is invalid (' . $hexcolor . ')', __FILE__, __LINE__); |
||||||||
3181 | |||||||||
3182 | return false; |
||||||||
3183 | } |
||||||||
3184 | $min_limit = (mb_strlen($min_limit) ? $min_limit : 5); |
||||||||
3185 | $max_limit = (mb_strlen($max_limit) ? $max_limit : 10); |
||||||||
3186 | if ($gdimg_mask = $phpthumbFilters->SourceTransparentColorMask($this->gdimg_output, $hexcolor, $min_limit, $max_limit)) { |
||||||||
3187 | $this->is_alpha = true; |
||||||||
3188 | $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output); |
||||||||
3189 | imagedestroy($gdimg_mask); |
||||||||
3190 | } else { |
||||||||
3191 | $this->DebugMessage('SourceTransparentColorMask() failed for "' . $hexcolor . ',' . $min_limit . ',' . $max_limit . '"', __FILE__, __LINE__); |
||||||||
3192 | } |
||||||||
3193 | break; |
||||||||
3194 | } |
||||||||
3195 | $this->DebugMessage('Finished processing filter command "' . $command . '(' . $parameter . ')"', __FILE__, __LINE__); |
||||||||
3196 | } |
||||||||
3197 | } |
||||||||
3198 | |||||||||
3199 | return true; |
||||||||
3200 | } |
||||||||
3201 | |||||||||
3202 | /** |
||||||||
3203 | * @return bool |
||||||||
3204 | */ |
||||||||
3205 | public function MaxFileSize() |
||||||||
3206 | { |
||||||||
3207 | if (phpthumb_functions::gd_version() < 2) { |
||||||||
3208 | $this->DebugMessage('Skipping MaxFileSize() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
3209 | |||||||||
3210 | return false; |
||||||||
3211 | } |
||||||||
3212 | if ($this->maxb > 0) { |
||||||||
3213 | switch ($this->thumbnailFormat) { |
||||||||
3214 | case 'png': |
||||||||
3215 | case 'gif': |
||||||||
3216 | $imgRenderFunction = 'image' . $this->thumbnailFormat; |
||||||||
3217 | |||||||||
3218 | ob_start(); |
||||||||
3219 | $imgRenderFunction($this->gdimg_output); |
||||||||
3220 | $imgdata = ob_get_contents(); |
||||||||
3221 | ob_end_clean(); |
||||||||
3222 | |||||||||
3223 | if (mb_strlen($imgdata) > $this->maxb) { |
||||||||
3224 | for ($i = 8; $i >= 1; $i--) { |
||||||||
3225 | $tempIMG = imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output)); |
||||||||
3226 | imagecopy($tempIMG, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output)); |
||||||||
3227 | imagetruecolortopalette($tempIMG, true, 2 ** $i); |
||||||||
3228 | ob_start(); |
||||||||
3229 | $imgRenderFunction($tempIMG); |
||||||||
3230 | $imgdata = ob_get_contents(); |
||||||||
3231 | ob_end_clean(); |
||||||||
3232 | |||||||||
3233 | if (mb_strlen($imgdata) <= $this->maxb) { |
||||||||
3234 | imagetruecolortopalette($this->gdimg_output, true, 2 ** $i); |
||||||||
3235 | break; |
||||||||
3236 | } |
||||||||
3237 | } |
||||||||
3238 | } |
||||||||
3239 | break; |
||||||||
3240 | case 'jpeg': |
||||||||
3241 | ob_start(); |
||||||||
3242 | imagejpeg($this->gdimg_output); |
||||||||
3243 | $imgdata = ob_get_contents(); |
||||||||
3244 | ob_end_clean(); |
||||||||
3245 | |||||||||
3246 | if (mb_strlen($imgdata) > $this->maxb) { |
||||||||
3247 | for ($i = 3; $i < 20; ++$i) { |
||||||||
3248 | $q = round(100 * (1 - log10($i / 2))); |
||||||||
3249 | ob_start(); |
||||||||
3250 | imagejpeg($this->gdimg_output, null, $q); |
||||||||
0 ignored issues
–
show
$q of type double is incompatible with the type integer expected by parameter $quality of imagejpeg() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3251 | $imgdata = ob_get_contents(); |
||||||||
3252 | ob_end_clean(); |
||||||||
3253 | |||||||||
3254 | $this->thumbnailQuality = $q; |
||||||||
3255 | if (mb_strlen($imgdata) <= $this->maxb) { |
||||||||
3256 | break; |
||||||||
3257 | } |
||||||||
3258 | } |
||||||||
3259 | } |
||||||||
3260 | if (mb_strlen($imgdata) > $this->maxb) { |
||||||||
3261 | return false; |
||||||||
3262 | } |
||||||||
3263 | break; |
||||||||
3264 | default: |
||||||||
3265 | return false; |
||||||||
3266 | } |
||||||||
3267 | } |
||||||||
3268 | |||||||||
3269 | return true; |
||||||||
3270 | } |
||||||||
3271 | |||||||||
3272 | /** |
||||||||
3273 | * @return bool |
||||||||
3274 | */ |
||||||||
3275 | public function CalculateThumbnailDimensions() |
||||||||
3276 | { |
||||||||
3277 | $this->DebugMessage('CalculateThumbnailDimensions() starting with [W,H,sx,sy,sw,sh] initially set to [' . $this->source_width . ',' . $this->source_height . ',' . $this->sx . ',' . $this->sy . ',' . $this->sw . ',' . $this->sh . ']', __FILE__, __LINE__); |
||||||||
3278 | //echo $this->source_width.'x'.$this->source_height.'<hr>'; |
||||||||
3279 | $this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width)) : 0); |
||||||||
3280 | //echo $this->thumbnailCropX.'<br>'; |
||||||||
3281 | $this->thumbnailCropY = ($this->sy ? (($this->sy >= 2) ? $this->sy : round($this->sy * $this->source_height)) : 0); |
||||||||
3282 | //echo $this->thumbnailCropY.'<br>'; |
||||||||
3283 | $this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width)) : $this->source_width); |
||||||||
3284 | //echo $this->thumbnailCropW.'<br>'; |
||||||||
3285 | $this->thumbnailCropH = ($this->sh ? (($this->sh >= 2) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height); |
||||||||
3286 | //echo $this->thumbnailCropH.'<hr>'; |
||||||||
3287 | |||||||||
3288 | // limit source area to original image area |
||||||||
3289 | $this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width - $this->thumbnailCropX)); |
||||||||
3290 | $this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY)); |
||||||||
3291 | |||||||||
3292 | $this->DebugMessage('CalculateThumbnailDimensions() starting with [x,y,w,h] initially set to [' . $this->thumbnailCropX . ',' . $this->thumbnailCropY . ',' . $this->thumbnailCropW . ',' . $this->thumbnailCropH . ']', __FILE__, __LINE__); |
||||||||
3293 | |||||||||
3294 | if ($this->zc && $this->w && $this->h) { |
||||||||
3295 | // Zoom Crop |
||||||||
3296 | // retain proportional resizing we did above, but crop off larger dimension so smaller |
||||||||
3297 | // dimension fully fits available space |
||||||||
3298 | |||||||||
3299 | $scaling_X = $this->source_width / $this->w; |
||||||||
3300 | $scaling_Y = $this->source_height / $this->h; |
||||||||
3301 | if ($scaling_X > $scaling_Y) { |
||||||||
3302 | // some of the width will need to be cropped |
||||||||
3303 | $allowable_width = $this->source_width / $scaling_X * $scaling_Y; |
||||||||
3304 | $this->thumbnailCropW = round($allowable_width); |
||||||||
3305 | $this->thumbnailCropX = round(($this->source_width - $allowable_width) / 2); |
||||||||
3306 | } elseif ($scaling_Y > $scaling_X) { |
||||||||
3307 | // some of the height will need to be cropped |
||||||||
3308 | $allowable_height = $this->source_height / $scaling_Y * $scaling_X; |
||||||||
3309 | $this->thumbnailCropH = round($allowable_height); |
||||||||
3310 | $this->thumbnailCropY = round(($this->source_height - $allowable_height) / 2); |
||||||||
3311 | } |
||||||||
3312 | // image fits perfectly, no cropping needed |
||||||||
3313 | |||||||||
3314 | $this->thumbnail_width = $this->w; |
||||||||
3315 | $this->thumbnail_height = $this->h; |
||||||||
3316 | $this->thumbnail_image_width = $this->thumbnail_width; |
||||||||
3317 | $this->thumbnail_image_height = $this->thumbnail_height; |
||||||||
3318 | } elseif ($this->iar && $this->w && $this->h) { |
||||||||
3319 | // Ignore Aspect Ratio |
||||||||
3320 | // stretch image to fit exactly 'w' x 'h' |
||||||||
3321 | $this->thumbnail_width = $this->w; |
||||||||
3322 | $this->thumbnail_height = $this->h; |
||||||||
3323 | $this->thumbnail_image_width = $this->thumbnail_width; |
||||||||
3324 | $this->thumbnail_image_height = $this->thumbnail_height; |
||||||||
3325 | } else { |
||||||||
3326 | $original_aspect_ratio = $this->thumbnailCropW / $this->thumbnailCropH; |
||||||||
3327 | if ($this->aoe) { |
||||||||
3328 | if ($this->w && $this->h) { |
||||||||
3329 | $maxwidth = min($this->w, $this->h * $original_aspect_ratio); |
||||||||
3330 | $maxheight = min($this->h, $this->w / $original_aspect_ratio); |
||||||||
3331 | } elseif ($this->w) { |
||||||||
3332 | $maxwidth = $this->w; |
||||||||
3333 | $maxheight = $this->w / $original_aspect_ratio; |
||||||||
3334 | } elseif ($this->h) { |
||||||||
3335 | $maxwidth = $this->h * $original_aspect_ratio; |
||||||||
3336 | $maxheight = $this->h; |
||||||||
3337 | } else { |
||||||||
3338 | $maxwidth = $this->thumbnailCropW; |
||||||||
3339 | $maxheight = $this->thumbnailCropH; |
||||||||
3340 | } |
||||||||
3341 | } else { |
||||||||
3342 | $maxwidth = phpthumb_functions::nonempty_min($this->w, $this->thumbnailCropW, $this->config_output_maxwidth); |
||||||||
3343 | $maxheight = phpthumb_functions::nonempty_min($this->h, $this->thumbnailCropH, $this->config_output_maxheight); |
||||||||
3344 | //echo $maxwidth.'x'.$maxheight.'<br>'; |
||||||||
3345 | $maxwidth = min($maxwidth, $maxheight * $original_aspect_ratio); |
||||||||
3346 | $maxheight = min($maxheight, $maxwidth / $original_aspect_ratio); |
||||||||
3347 | //echo $maxwidth.'x'.$maxheight.'<hr>'; |
||||||||
3348 | } |
||||||||
3349 | |||||||||
3350 | $this->thumbnail_image_width = $maxwidth; |
||||||||
3351 | $this->thumbnail_image_height = $maxheight; |
||||||||
3352 | $this->thumbnail_width = $maxwidth; |
||||||||
3353 | $this->thumbnail_height = $maxheight; |
||||||||
3354 | |||||||||
3355 | $this->FixedAspectRatio(); |
||||||||
3356 | } |
||||||||
3357 | |||||||||
3358 | $this->thumbnail_width = max(1, floor($this->thumbnail_width)); |
||||||||
3359 | $this->thumbnail_height = max(1, floor($this->thumbnail_height)); |
||||||||
3360 | |||||||||
3361 | return true; |
||||||||
3362 | } |
||||||||
3363 | |||||||||
3364 | /** |
||||||||
3365 | * @return bool |
||||||||
3366 | */ |
||||||||
3367 | public function CreateGDoutput() |
||||||||
3368 | { |
||||||||
3369 | $this->CalculateThumbnailDimensions(); |
||||||||
3370 | |||||||||
3371 | // create the GD image (either true-color or 256-color, depending on GD version) |
||||||||
3372 | $this->gdimg_output = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height); |
||||||||
3373 | |||||||||
3374 | // images that have transparency must have the background filled with the configured 'bg' color otherwise the transparent color will appear as black |
||||||||
3375 | imagesavealpha($this->gdimg_output, true); |
||||||||
3376 | if ($this->is_alpha && phpthumb_functions::gd_version() >= 2) { |
||||||||
3377 | imagealphablending($this->gdimg_output, false); |
||||||||
3378 | $output_full_alpha = phpthumb_functions::ImageColorAllocateAlphaSafe($this->gdimg_output, 255, 255, 255, 127); |
||||||||
3379 | imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $output_full_alpha); |
||||||||
3380 | } else { |
||||||||
3381 | $current_transparent_color = imagecolortransparent($this->gdimg_source); |
||||||||
3382 | if ($this->bg || (@$current_transparent_color >= 0)) { |
||||||||
3383 | $this->config_background_hexcolor = ($this->bg ?: $this->config_background_hexcolor); |
||||||||
3384 | if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) { |
||||||||
3385 | return $this->ErrorImage('Invalid hex color string "' . $this->config_background_hexcolor . '" for parameter "bg"'); |
||||||||
3386 | } |
||||||||
3387 | $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor); |
||||||||
3388 | imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color); |
||||||||
3389 | } |
||||||||
3390 | } |
||||||||
3391 | $this->DebugMessage('CreateGDoutput() returning canvas "' . $this->thumbnail_width . 'x' . $this->thumbnail_height . '"', __FILE__, __LINE__); |
||||||||
3392 | |||||||||
3393 | return true; |
||||||||
3394 | } |
||||||||
3395 | |||||||||
3396 | /** |
||||||||
3397 | * @return bool |
||||||||
3398 | */ |
||||||||
3399 | public function SetOrientationDependantWidthHeight() |
||||||||
3400 | { |
||||||||
3401 | $this->DebugMessage('SetOrientationDependantWidthHeight() starting with "' . $this->source_width . '"x"' . $this->source_height . '"', __FILE__, __LINE__); |
||||||||
3402 | if ($this->source_height > $this->source_width) { |
||||||||
3403 | // portrait |
||||||||
3404 | $this->w = phpthumb_functions::OneOfThese($this->wp, $this->w, $this->ws, $this->wl); |
||||||||
3405 | $this->h = phpthumb_functions::OneOfThese($this->hp, $this->h, $this->hs, $this->hl); |
||||||||
3406 | } elseif ($this->source_height < $this->source_width) { |
||||||||
3407 | // landscape |
||||||||
3408 | $this->w = phpthumb_functions::OneOfThese($this->wl, $this->w, $this->ws, $this->wp); |
||||||||
3409 | $this->h = phpthumb_functions::OneOfThese($this->hl, $this->h, $this->hs, $this->hp); |
||||||||
3410 | } else { |
||||||||
3411 | // square |
||||||||
3412 | $this->w = phpthumb_functions::OneOfThese($this->ws, $this->w, $this->wl, $this->wp); |
||||||||
3413 | $this->h = phpthumb_functions::OneOfThese($this->hs, $this->h, $this->hl, $this->hp); |
||||||||
3414 | } |
||||||||
3415 | //$this->w = round($this->w ? $this->w : (($this->h && $this->source_height) ? $this->h * $this->source_width / $this->source_height : $this->w)); |
||||||||
3416 | //$this->h = round($this->h ? $this->h : (($this->w && $this->source_width) ? $this->w * $this->source_height / $this->source_width : $this->h)); |
||||||||
3417 | $this->DebugMessage('SetOrientationDependantWidthHeight() setting w="' . (int)$this->w . '", h="' . (int)$this->h . '"', __FILE__, __LINE__); |
||||||||
3418 | |||||||||
3419 | return true; |
||||||||
3420 | } |
||||||||
3421 | |||||||||
3422 | /** |
||||||||
3423 | * @return bool |
||||||||
3424 | */ |
||||||||
3425 | public function ExtractEXIFgetImageSize() |
||||||||
3426 | { |
||||||||
3427 | $this->DebugMessage('starting ExtractEXIFgetImageSize()', __FILE__, __LINE__); |
||||||||
3428 | |||||||||
3429 | if (preg_match('#^http:#i', $this->src) && !$this->sourceFilename && $this->rawImageData) { |
||||||||
3430 | $this->SourceDataToTempFile(); |
||||||||
3431 | } |
||||||||
3432 | if (null === $this->getimagesizeinfo) { |
||||||||
3433 | if ($this->sourceFilename) { |
||||||||
3434 | $this->getimagesizeinfo = @getimagesize($this->sourceFilename); |
||||||||
3435 | $this->source_width = $this->getimagesizeinfo[0]; |
||||||||
3436 | $this->source_height = $this->getimagesizeinfo[1]; |
||||||||
3437 | $this->DebugMessage('getimagesize(' . $this->sourceFilename . ') says image is ' . $this->source_width . 'x' . $this->source_height, __FILE__, __LINE__); |
||||||||
3438 | } else { |
||||||||
3439 | $this->DebugMessage('skipping getimagesize() because $this->sourceFilename is empty', __FILE__, __LINE__); |
||||||||
3440 | } |
||||||||
3441 | } else { |
||||||||
3442 | $this->DebugMessage('skipping getimagesize() because !is_null($this->getimagesizeinfo)', __FILE__, __LINE__); |
||||||||
3443 | } |
||||||||
3444 | |||||||||
3445 | if (is_resource($this->gdimg_source)) { |
||||||||
3446 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
3447 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
3448 | |||||||||
3449 | $this->SetOrientationDependantWidthHeight(); |
||||||||
3450 | } elseif ($this->rawImageData && !$this->sourceFilename) { |
||||||||
3451 | if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { |
||||||||
3452 | $this->DebugMessage('NOT bypassing EXIF and getimagesize sections because source image is too large for GD (' . $this->source_width . 'x' . $this->source_width . '=' . ($this->source_width * $this->source_height * 5) . 'MB)', __FILE__, __LINE__); |
||||||||
3453 | } else { |
||||||||
3454 | $this->DebugMessage( |
||||||||
3455 | 'bypassing EXIF and getimagesize sections because $this->rawImageData is set, and $this->sourceFilename is not set, and source image is not too large for GD (' . $this->source_width . 'x' . $this->source_width . '=' . ($this->source_width * $this->source_height * 5) . 'MB)', |
||||||||
3456 | __FILE__, |
||||||||
3457 | __LINE__ |
||||||||
3458 | ); |
||||||||
3459 | } |
||||||||
3460 | } |
||||||||
3461 | |||||||||
3462 | if (null === $this->getimagesizeinfo) { |
||||||||
3463 | $this->getimagesizeinfo = @getimagesize($this->sourceFilename); |
||||||||
3464 | } |
||||||||
3465 | |||||||||
3466 | if (!empty($this->getimagesizeinfo)) { |
||||||||
3467 | // great |
||||||||
3468 | $this->getimagesizeinfo['filesize'] = @filesize($this->sourceFilename); |
||||||||
3469 | } elseif (!$this->rawImageData) { |
||||||||
3470 | $this->DebugMessage('getimagesize("' . $this->sourceFilename . '") failed', __FILE__, __LINE__); |
||||||||
3471 | } |
||||||||
3472 | |||||||||
3473 | if ($this->config_prefer_imagemagick) { |
||||||||
3474 | if ($this->ImageMagickThumbnailToGD()) { |
||||||||
3475 | return true; |
||||||||
3476 | } |
||||||||
3477 | $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); |
||||||||
3478 | } |
||||||||
3479 | |||||||||
3480 | $this->source_width = $this->getimagesizeinfo[0]; |
||||||||
3481 | $this->source_height = $this->getimagesizeinfo[1]; |
||||||||
3482 | |||||||||
3483 | $this->SetOrientationDependantWidthHeight(); |
||||||||
3484 | |||||||||
3485 | if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=') |
||||||||
3486 | && function_exists('exif_read_data')) { |
||||||||
3487 | switch ($this->getimagesizeinfo[2]) { |
||||||||
3488 | case IMAGETYPE_JPEG: |
||||||||
3489 | case IMAGETYPE_TIFF_II: |
||||||||
3490 | case IMAGETYPE_TIFF_MM: |
||||||||
3491 | $this->exif_raw_data = @exif_read_data($this->sourceFilename, 0, true); |
||||||||
3492 | break; |
||||||||
3493 | } |
||||||||
3494 | } |
||||||||
3495 | if (function_exists('exif_thumbnail') && (IMAGETYPE_JPEG == $this->getimagesizeinfo[2])) { |
||||||||
3496 | // Extract EXIF info from JPEGs |
||||||||
3497 | |||||||||
3498 | $this->exif_thumbnail_width = ''; |
||||||||
3499 | $this->exif_thumbnail_height = ''; |
||||||||
3500 | $this->exif_thumbnail_type = ''; |
||||||||
3501 | |||||||||
3502 | // The parameters width, height and imagetype are available since PHP v4.3.0 |
||||||||
3503 | if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) { |
||||||||
3504 | $this->exif_thumbnail_data = @exif_thumbnail($this->sourceFilename, $this->exif_thumbnail_width, $this->exif_thumbnail_height, $this->exif_thumbnail_type); |
||||||||
0 ignored issues
–
show
$this->exif_thumbnail_width of type string is incompatible with the type integer expected by parameter $width of exif_thumbnail() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $this->exif_thumbnail_height of type string is incompatible with the type integer expected by parameter $height of exif_thumbnail() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $this->exif_thumbnail_type of type string is incompatible with the type integer expected by parameter $image_type of exif_thumbnail() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3505 | } else { |
||||||||
3506 | // older versions of exif_thumbnail output an error message but NOT return false on failure |
||||||||
3507 | ob_start(); |
||||||||
3508 | $this->exif_thumbnail_data = exif_thumbnail($this->sourceFilename); |
||||||||
3509 | $exit_thumbnail_error = ob_get_contents(); |
||||||||
3510 | ob_end_clean(); |
||||||||
3511 | if (!$exit_thumbnail_error && $this->exif_thumbnail_data) { |
||||||||
3512 | if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { |
||||||||
3513 | $this->exif_thumbnail_width = imagesx($gdimg_exif_temp); |
||||||||
3514 | $this->exif_thumbnail_height = imagesy($gdimg_exif_temp); |
||||||||
3515 | $this->exif_thumbnail_type = 2; // (2 == JPEG) before PHP v4.3.0 only JPEG format EXIF thumbnails are returned |
||||||||
3516 | unset($gdimg_exif_temp); |
||||||||
3517 | } else { |
||||||||
3518 | return $this->ErrorImage('Failed - $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data) in ' . __FILE__ . ' on line ' . __LINE__); |
||||||||
3519 | } |
||||||||
3520 | } |
||||||||
3521 | } |
||||||||
3522 | } elseif (!function_exists('exif_thumbnail')) { |
||||||||
3523 | $this->DebugMessage('exif_thumbnail() does not exist, cannot extract EXIF thumbnail', __FILE__, __LINE__); |
||||||||
3524 | } |
||||||||
3525 | |||||||||
3526 | $this->DebugMessage('EXIF thumbnail extraction: (size=' . mb_strlen($this->exif_thumbnail_data) . '; type="' . $this->exif_thumbnail_type . '"; ' . (int)$this->exif_thumbnail_width . 'x' . (int)$this->exif_thumbnail_height . ')', __FILE__, __LINE__); |
||||||||
3527 | |||||||||
3528 | // see if EXIF thumbnail can be used directly with no processing |
||||||||
3529 | if ($this->config_use_exif_thumbnail_for_speed && $this->exif_thumbnail_data) { |
||||||||
3530 | while (true) { |
||||||||
3531 | if (!$this->xto) { |
||||||||
3532 | $source_ar = $this->source_width / $this->source_height; |
||||||||
3533 | $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height; |
||||||||
3534 | if (number_format($source_ar, 2) != number_format($exif_ar, 2)) { |
||||||||
3535 | $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar (' . $source_ar . ' != ' . $exif_ar . ')', __FILE__, __LINE__); |
||||||||
3536 | break; |
||||||||
3537 | } |
||||||||
3538 | if ($this->w && ($this->w != $this->exif_thumbnail_width)) { |
||||||||
3539 | $this->DebugMessage('not using EXIF thumbnail because $this->w != $this->exif_thumbnail_width (' . $this->w . ' != ' . $this->exif_thumbnail_width . ')', __FILE__, __LINE__); |
||||||||
3540 | break; |
||||||||
3541 | } |
||||||||
3542 | if ($this->h && ($this->h != $this->exif_thumbnail_height)) { |
||||||||
3543 | $this->DebugMessage('not using EXIF thumbnail because $this->h != $this->exif_thumbnail_height (' . $this->h . ' != ' . $this->exif_thumbnail_height . ')', __FILE__, __LINE__); |
||||||||
3544 | break; |
||||||||
3545 | } |
||||||||
3546 | $CannotBeSetParameters = ['sx', 'sy', 'sh', 'sw', 'far', 'bg', 'bc', 'fltr', 'phpThumbDebug']; |
||||||||
3547 | foreach ($CannotBeSetParameters as $parameter) { |
||||||||
3548 | if ($this->$parameter) { |
||||||||
3549 | break 2; |
||||||||
3550 | } |
||||||||
3551 | } |
||||||||
3552 | } |
||||||||
3553 | |||||||||
3554 | $this->DebugMessage('setting $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data)', __FILE__, __LINE__); |
||||||||
3555 | $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data); |
||||||||
3556 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
3557 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
3558 | |||||||||
3559 | return true; |
||||||||
3560 | } |
||||||||
3561 | } |
||||||||
3562 | |||||||||
3563 | if (($this->config_max_source_pixels > 0) |
||||||||
3564 | && (($this->source_width * $this->source_height) > $this->config_max_source_pixels)) { |
||||||||
3565 | // Source image is larger than would fit in available PHP memory. |
||||||||
3566 | // If ImageMagick is installed, use it to generate the thumbnail. |
||||||||
3567 | // Else, if an EXIF thumbnail is available, use that as the source image. |
||||||||
3568 | // Otherwise, no choice but to fail with an error message |
||||||||
3569 | $this->DebugMessage('image is ' . $this->source_width . 'x' . $this->source_height . ' and therefore contains more pixels (' . ($this->source_width * $this->source_height) . ') than $this->config_max_source_pixels setting (' . $this->config_max_source_pixels . ')', __FILE__, __LINE__); |
||||||||
3570 | if (!$this->config_prefer_imagemagick && $this->ImageMagickThumbnailToGD()) { |
||||||||
3571 | // excellent, we have a thumbnailed source image |
||||||||
3572 | return true; |
||||||||
3573 | } |
||||||||
3574 | } |
||||||||
3575 | |||||||||
3576 | return true; |
||||||||
3577 | } |
||||||||
3578 | |||||||||
3579 | /** |
||||||||
3580 | * @return bool |
||||||||
3581 | */ |
||||||||
3582 | public function SetCacheFilename() |
||||||||
3583 | { |
||||||||
3584 | if (null !== $this->cache_filename) { |
||||||||
3585 | $this->DebugMessage('$this->cache_filename already set, skipping SetCacheFilename()', __FILE__, __LINE__); |
||||||||
3586 | |||||||||
3587 | return true; |
||||||||
3588 | } |
||||||||
3589 | if (null === $this->config_cache_directory) { |
||||||||
3590 | $this->setCacheDirectory(); |
||||||||
3591 | if (!$this->config_cache_directory) { |
||||||||
3592 | $this->DebugMessage('SetCacheFilename() failed because $this->config_cache_directory is empty', __FILE__, __LINE__); |
||||||||
3593 | |||||||||
3594 | return false; |
||||||||
3595 | } |
||||||||
3596 | } |
||||||||
3597 | $this->setOutputFormat(); |
||||||||
3598 | |||||||||
3599 | if (!$this->sourceFilename && !$this->rawImageData && $this->src) { |
||||||||
3600 | $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src); |
||||||||
3601 | } |
||||||||
3602 | |||||||||
3603 | if ($this->config_cache_default_only_suffix && $this->sourceFilename) { |
||||||||
3604 | // simplified cache filenames: |
||||||||
3605 | // only use default parameters in phpThumb.config.php |
||||||||
3606 | // substitute source filename into * in $this->config_cache_default_only_suffix |
||||||||
3607 | // (eg: '*_thumb' becomes 'picture_thumb.jpg') |
||||||||
3608 | if (false === mb_strpos($this->config_cache_default_only_suffix, '*')) { |
||||||||
0 ignored issues
–
show
$this->config_cache_default_only_suffix of type true is incompatible with the type string expected by parameter $haystack of mb_strpos() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3609 | $this->DebugMessage('aborting simplified caching filename because no * in "' . $this->config_cache_default_only_suffix . '"', __FILE__, __LINE__); |
||||||||
0 ignored issues
–
show
Are you sure
$this->config_cache_default_only_suffix of type true can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3610 | } else { |
||||||||
3611 | preg_match('#(.+)(\\.[a-z0-9]+)?$#i', basename($this->sourceFilename), $matches); |
||||||||
3612 | $this->cache_filename = $this->config_cache_directory . DIRECTORY_SEPARATOR . rawurlencode(str_replace('*', @$matches[1], $this->config_cache_default_only_suffix)) . '.' . mb_strtolower($this->thumbnailFormat); |
||||||||
3613 | |||||||||
3614 | return true; |
||||||||
3615 | } |
||||||||
3616 | } |
||||||||
3617 | |||||||||
3618 | $this->cache_filename = ''; |
||||||||
3619 | if ($this->new) { |
||||||||
3620 | $broad_directory_name = mb_strtolower(md5($this->new)); |
||||||||
3621 | $this->cache_filename .= '_new' . $broad_directory_name; |
||||||||
3622 | } elseif ($this->md5s) { |
||||||||
3623 | // source image MD5 hash provided |
||||||||
3624 | $this->DebugMessage('SetCacheFilename() _raw set from $this->md5s = "' . $this->md5s . '"', __FILE__, __LINE__); |
||||||||
3625 | $broad_directory_name = $this->md5s; |
||||||||
3626 | $this->cache_filename .= '_raw' . $this->md5s; |
||||||||
3627 | } elseif (!$this->src && $this->rawImageData) { |
||||||||
3628 | $this->DebugMessage('SetCacheFilename() _raw set from md5($this->rawImageData) = "' . md5($this->rawImageData) . '"', __FILE__, __LINE__); |
||||||||
3629 | $broad_directory_name = mb_strtolower(md5($this->rawImageData)); |
||||||||
3630 | $this->cache_filename .= '_raw' . $broad_directory_name; |
||||||||
3631 | } else { |
||||||||
3632 | $this->DebugMessage('SetCacheFilename() _src set from md5($this->sourceFilename) "' . $this->sourceFilename . '" = "' . md5($this->sourceFilename) . '"', __FILE__, __LINE__); |
||||||||
3633 | $broad_directory_name = mb_strtolower(md5($this->sourceFilename)); |
||||||||
3634 | $this->cache_filename .= '_src' . $broad_directory_name; |
||||||||
3635 | } |
||||||||
3636 | if (!empty(\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER')) && $this->config_nooffsitelink_enabled) { |
||||||||
3637 | $parsed_url1 = @phpthumb_functions::ParseURLbetter(@\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER')); |
||||||||
3638 | $parsed_url2 = @phpthumb_functions::ParseURLbetter('http://' . @$_SERVER['HTTP_HOST']); |
||||||||
3639 | if (@$parsed_url1['host'] && @$parsed_url2['host'] && ($parsed_url1['host'] != $parsed_url2['host'])) { |
||||||||
3640 | // include "_offsite" only if nooffsitelink_enabled and if referrer doesn't match the domain of the current server |
||||||||
3641 | $this->cache_filename .= '_offsite'; |
||||||||
3642 | } |
||||||||
3643 | } |
||||||||
3644 | |||||||||
3645 | $ParametersString = ''; |
||||||||
3646 | if ($this->fltr && is_array($this->fltr)) { |
||||||||
0 ignored issues
–
show
The expression
$this->fltr of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||||||
3647 | $ParametersString .= '_fltr' . implode('_fltr', $this->fltr); |
||||||||
3648 | } |
||||||||
3649 | $FilenameParameters1 = ['ar', 'bg', 'bc', 'far', 'sx', 'sy', 'sw', 'sh', 'zc']; |
||||||||
3650 | foreach ($FilenameParameters1 as $key) { |
||||||||
3651 | if ($this->$key) { |
||||||||
3652 | $ParametersString .= '_' . $key . $this->$key; |
||||||||
3653 | } |
||||||||
3654 | } |
||||||||
3655 | $FilenameParameters2 = [ |
||||||||
3656 | 'h', |
||||||||
3657 | 'w', |
||||||||
3658 | 'wl', |
||||||||
3659 | 'wp', |
||||||||
3660 | 'ws', |
||||||||
3661 | 'hp', |
||||||||
3662 | 'hs', |
||||||||
3663 | 'xto', |
||||||||
3664 | 'ra', |
||||||||
3665 | 'iar', |
||||||||
3666 | 'aoe', |
||||||||
3667 | 'maxb', |
||||||||
3668 | 'sfn', |
||||||||
3669 | 'dpi', |
||||||||
3670 | ]; |
||||||||
3671 | foreach ($FilenameParameters2 as $key) { |
||||||||
3672 | if ($this->$key) { |
||||||||
3673 | $ParametersString .= '_' . $key . (int)$this->$key; |
||||||||
3674 | } |
||||||||
3675 | } |
||||||||
3676 | if ('jpeg' === $this->thumbnailFormat) { |
||||||||
3677 | // only JPEG output has variable quality option |
||||||||
3678 | $ParametersString .= '_q' . (int)$this->thumbnailQuality; |
||||||||
3679 | } |
||||||||
3680 | $this->DebugMessage('SetCacheFilename() _par set from md5(' . $ParametersString . ')', __FILE__, __LINE__); |
||||||||
3681 | $this->cache_filename .= '_par' . mb_strtolower(md5($ParametersString)); |
||||||||
3682 | |||||||||
3683 | if ($this->md5s) { |
||||||||
3684 | // source image MD5 hash provided |
||||||||
3685 | // do not source image modification date -- |
||||||||
3686 | // cached image will be used even if file was modified or removed |
||||||||
3687 | } elseif (!$this->config_cache_source_filemtime_ignore_remote && preg_match('#^(f|ht)tps?\://#i', $this->src)) { |
||||||||
3688 | $this->cache_filename .= '_dat' . (int)phpthumb_functions::filedate_remote($this->src); |
||||||||
3689 | } elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) { |
||||||||
3690 | $this->cache_filename .= '_dat' . (int)(@filemtime($this->sourceFilename)); |
||||||||
3691 | } |
||||||||
3692 | |||||||||
3693 | $this->cache_filename .= '.' . mb_strtolower($this->thumbnailFormat); |
||||||||
3694 | $broad_directories = ''; |
||||||||
3695 | for ($i = 0; $i < $this->config_cache_directory_depth; ++$i) { |
||||||||
3696 | $broad_directories .= DIRECTORY_SEPARATOR . mb_substr($broad_directory_name, 0, $i + 1); |
||||||||
3697 | } |
||||||||
3698 | |||||||||
3699 | $this->cache_filename = $this->config_cache_directory . $broad_directories . DIRECTORY_SEPARATOR . $this->config_cache_prefix . rawurlencode($this->cache_filename); |
||||||||
3700 | |||||||||
3701 | return true; |
||||||||
3702 | } |
||||||||
3703 | |||||||||
3704 | /** |
||||||||
3705 | * @param $width |
||||||||
3706 | * @param $height |
||||||||
3707 | * @return bool |
||||||||
3708 | */ |
||||||||
3709 | public function SourceImageIsTooLarge($width, $height) |
||||||||
3710 | { |
||||||||
3711 | if (!$this->config_max_source_pixels) { |
||||||||
3712 | return false; |
||||||||
3713 | } |
||||||||
3714 | if ($this->php_memory_limit && function_exists('memory_get_usage')) { |
||||||||
3715 | $available_memory = $this->php_memory_limit - memory_get_usage(); |
||||||||
3716 | |||||||||
3717 | return (($width * $height * 5) > $available_memory); |
||||||||
3718 | } |
||||||||
3719 | |||||||||
3720 | return (($width * $height) > $this->config_max_source_pixels); |
||||||||
3721 | } |
||||||||
3722 | |||||||||
3723 | /** |
||||||||
3724 | * @param $filename |
||||||||
3725 | * @return bool|resource |
||||||||
3726 | */ |
||||||||
3727 | public function ImageCreateFromFilename($filename) |
||||||||
3728 | { |
||||||||
3729 | // try to create GD image source directly via GD, if possible, |
||||||||
3730 | // rather than buffering to memory and creating with imagecreatefromstring |
||||||||
3731 | $ImageCreateWasAttempted = false; |
||||||||
3732 | $gd_image = false; |
||||||||
3733 | |||||||||
3734 | $this->DebugMessage('starting ImageCreateFromFilename(' . $filename . ')', __FILE__, __LINE__); |
||||||||
3735 | if ($filename && ($getimagesizeinfo = @getimagesize($filename))) { |
||||||||
3736 | if (!$this->SourceImageIsTooLarge($getimagesizeinfo[0], $getimagesizeinfo[1])) { |
||||||||
3737 | $ImageCreateFromFunction = [ |
||||||||
3738 | 1 => 'imagecreatefromgif', |
||||||||
3739 | 2 => 'imagecreatefromjpeg', |
||||||||
3740 | 3 => 'imagecreatefrompng', |
||||||||
3741 | 15 => 'imagecreatefromwbmp', |
||||||||
3742 | ]; |
||||||||
3743 | $this->DebugMessage('ImageCreateFromFilename found ($getimagesizeinfo[2]==' . @$getimagesizeinfo[2] . ')', __FILE__, __LINE__); |
||||||||
3744 | switch (@$getimagesizeinfo[2]) { |
||||||||
3745 | case 1: // GIF |
||||||||
3746 | case 2: // JPEG |
||||||||
3747 | case 3: // PNG |
||||||||
3748 | case 15: // WBMP |
||||||||
3749 | $ImageCreateFromFunctionName = $ImageCreateFromFunction[$getimagesizeinfo[2]]; |
||||||||
3750 | if (function_exists($ImageCreateFromFunctionName)) { |
||||||||
3751 | $this->DebugMessage('Calling ' . $ImageCreateFromFunctionName . '(' . $filename . ')', __FILE__, __LINE__); |
||||||||
3752 | $ImageCreateWasAttempted = true; |
||||||||
3753 | $gd_image = $ImageCreateFromFunctionName($filename); |
||||||||
3754 | } else { |
||||||||
3755 | $this->DebugMessage('NOT calling ' . $ImageCreateFromFunctionName . '(' . $filename . ') because !function_exists(' . $ImageCreateFromFunctionName . ')', __FILE__, __LINE__); |
||||||||
3756 | } |
||||||||
3757 | break; |
||||||||
3758 | case 4: // SWF |
||||||||
3759 | case 5: // PSD |
||||||||
3760 | case 6: // BMP |
||||||||
3761 | case 7: // TIFF (LE) |
||||||||
3762 | case 8: // TIFF (BE) |
||||||||
3763 | case 9: // JPC |
||||||||
3764 | case 10: // JP2 |
||||||||
3765 | case 11: // JPX |
||||||||
3766 | case 12: // JB2 |
||||||||
3767 | case 13: // SWC |
||||||||
3768 | case 14: // IFF |
||||||||
3769 | case 16: // XBM |
||||||||
3770 | $this->DebugMessage('No built-in image creation function for image type "' . @$getimagesizeinfo[2] . '" ($getimagesizeinfo[2])', __FILE__, __LINE__); |
||||||||
3771 | break; |
||||||||
3772 | default: |
||||||||
3773 | $this->DebugMessage('Unknown value for $getimagesizeinfo[2]: "' . @$getimagesizeinfo[2] . '"', __FILE__, __LINE__); |
||||||||
3774 | break; |
||||||||
3775 | } |
||||||||
3776 | } else { |
||||||||
3777 | $this->DebugMessage( |
||||||||
3778 | 'image is ' . $getimagesizeinfo[0] . 'x' . $getimagesizeinfo[1] . ' and therefore contains more pixels (' . ($getimagesizeinfo[0] * $getimagesizeinfo[1]) . ') than $this->config_max_source_pixels setting (' . $this->config_max_source_pixels . ')', |
||||||||
3779 | __FILE__, |
||||||||
3780 | __LINE__ |
||||||||
3781 | ); |
||||||||
3782 | |||||||||
3783 | return false; |
||||||||
3784 | } |
||||||||
3785 | } else { |
||||||||
3786 | $this->DebugMessage('empty $filename or getimagesize(' . $filename . ') failed', __FILE__, __LINE__); |
||||||||
3787 | } |
||||||||
3788 | |||||||||
3789 | if (!$gd_image) { |
||||||||
3790 | // cannot create from filename, attempt to create source image with imagecreatefromstring, if possible |
||||||||
3791 | if ($ImageCreateWasAttempted) { |
||||||||
3792 | $this->DebugMessage($ImageCreateFromFunctionName . '() was attempted but FAILED', __FILE__, __LINE__); |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
3793 | } |
||||||||
3794 | $this->DebugMessage('Populating $rawimagedata', __FILE__, __LINE__); |
||||||||
3795 | $rawimagedata = ''; |
||||||||
3796 | if ($fp = @fopen($filename, 'rb')) { |
||||||||
3797 | $filesize = filesize($filename); |
||||||||
3798 | $blocksize = 8192; |
||||||||
3799 | $blockreads = ceil($filesize / $blocksize); |
||||||||
3800 | for ($i = 0; $i < $blockreads; ++$i) { |
||||||||
3801 | $rawimagedata .= fread($fp, $blocksize); |
||||||||
3802 | } |
||||||||
3803 | fclose($fp); |
||||||||
3804 | } else { |
||||||||
3805 | $this->DebugMessage('cannot fopen(' . $filename . ')', __FILE__, __LINE__); |
||||||||
3806 | } |
||||||||
3807 | if ($rawimagedata) { |
||||||||
3808 | $this->DebugMessage('attempting ImageCreateFromStringReplacement($rawimagedata (' . mb_strlen($rawimagedata) . ' bytes), true)', __FILE__, __LINE__); |
||||||||
3809 | $gd_image = $this->ImageCreateFromStringReplacement($rawimagedata, true); |
||||||||
3810 | } |
||||||||
3811 | } |
||||||||
3812 | |||||||||
3813 | return $gd_image; |
||||||||
3814 | } |
||||||||
3815 | |||||||||
3816 | /** |
||||||||
3817 | * @return bool |
||||||||
3818 | */ |
||||||||
3819 | public function SourceImageToGD() |
||||||||
3820 | { |
||||||||
3821 | if (is_resource($this->gdimg_source)) { |
||||||||
3822 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
3823 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
3824 | $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); |
||||||||
3825 | |||||||||
3826 | return true; |
||||||||
3827 | } |
||||||||
3828 | $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__); |
||||||||
3829 | |||||||||
3830 | if ($this->config_prefer_imagemagick) { |
||||||||
3831 | if (empty($this->sourceFilename) && !empty($this->rawImageData)) { |
||||||||
3832 | $this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__); |
||||||||
3833 | if ($tempnam = $this->phpThumb_tempnam()) { |
||||||||
3834 | if (file_put_contents($tempnam, $this->rawImageData)) { |
||||||||
3835 | $this->sourceFilename = $tempnam; |
||||||||
3836 | if ($this->ImageMagickThumbnailToGD()) { |
||||||||
3837 | // excellent, we have a thumbnailed source image |
||||||||
3838 | $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__); |
||||||||
3839 | } else { |
||||||||
3840 | $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); |
||||||||
3841 | } |
||||||||
3842 | } else { |
||||||||
3843 | $this->DebugMessage('failed to put $this->rawImageData into temp file "' . $tempnam . '"', __FILE__, __LINE__); |
||||||||
3844 | } |
||||||||
3845 | } else { |
||||||||
3846 | $this->DebugMessage('failed to generate temp file name', __FILE__, __LINE__); |
||||||||
3847 | } |
||||||||
3848 | } |
||||||||
3849 | } |
||||||||
3850 | if (!$this->gdimg_source && $this->rawImageData) { |
||||||||
3851 | if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { |
||||||||
3852 | $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0); |
||||||||
3853 | |||||||||
3854 | return $this->ErrorImage( |
||||||||
3855 | 'Source image is too large (' |
||||||||
3856 | . $this->source_width |
||||||||
3857 | . 'x' |
||||||||
3858 | . $this->source_height |
||||||||
3859 | . ' = ' |
||||||||
3860 | . number_format($this->source_width * $this->source_height / 1000000, 1) |
||||||||
3861 | . 'Mpx, max=' |
||||||||
3862 | . number_format($this->config_max_source_pixels / 1000000, 1) |
||||||||
3863 | . 'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least ' |
||||||||
3864 | . ceil(($memory_get_usage + (5 * $this->source_width * $this->source_height)) / 1048576) |
||||||||
3865 | . 'M).' |
||||||||
3866 | ); |
||||||||
3867 | } |
||||||||
3868 | if ($this->md5s && ($this->md5s != md5($this->rawImageData))) { |
||||||||
3869 | return $this->ErrorImage('$this->md5s != md5($this->rawImageData)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . md5($this->rawImageData) . '"'); |
||||||||
3870 | } |
||||||||
3871 | //if ($this->issafemode) { |
||||||||
3872 | // return $this->ErrorImage('Cannot generate thumbnails from raw image data when PHP SAFE_MODE enabled'); |
||||||||
3873 | //} |
||||||||
3874 | $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData); |
||||||||
3875 | if (!$this->gdimg_source) { |
||||||||
3876 | if ('BM' === mb_substr($this->rawImageData, 0, 2)) { |
||||||||
3877 | $this->getimagesizeinfo[2] = 6; // BMP |
||||||||
3878 | } elseif (mb_substr($this->rawImageData, 0, 4) === 'II' . "\x2A\x00") { |
||||||||
3879 | $this->getimagesizeinfo[2] = 7; // TIFF (littlendian) |
||||||||
3880 | } elseif (mb_substr($this->rawImageData, 0, 4) === 'MM' . "\x00\x2A") { |
||||||||
3881 | $this->getimagesizeinfo[2] = 8; // TIFF (bigendian) |
||||||||
3882 | } |
||||||||
3883 | $this->DebugMessage('SourceImageToGD.ImageCreateFromStringReplacement() failed with unknown image type "' . mb_substr($this->rawImageData, 0, 4) . '" (' . phpthumb_functions::HexCharDisplay(mb_substr($this->rawImageData, 0, 4)) . ')', __FILE__, __LINE__); |
||||||||
3884 | // return $this->ErrorImage('Unknown image type identified by "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).') in SourceImageToGD()['.__LINE__.']'); |
||||||||
3885 | } |
||||||||
3886 | } elseif (!$this->gdimg_source && $this->sourceFilename) { |
||||||||
3887 | if ($this->md5s && ($this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename))) { |
||||||||
3888 | return $this->ErrorImage('$this->md5s != md5(sourceFilename)' . "\n" . '"' . $this->md5s . '" != ' . "\n" . '"' . phpthumb_functions::md5_file_safe($this->sourceFilename) . '"'); |
||||||||
0 ignored issues
–
show
Are you sure
phpthumb_functions::md5_...($this->sourceFilename) of type false|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
3889 | } |
||||||||
3890 | switch (@$this->getimagesizeinfo[2]) { |
||||||||
3891 | case 1: |
||||||||
3892 | case 3: |
||||||||
3893 | // GIF or PNG input file may have transparency |
||||||||
3894 | $this->is_alpha = true; |
||||||||
3895 | break; |
||||||||
3896 | } |
||||||||
3897 | if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) { |
||||||||
3898 | $this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename); |
||||||||
3899 | } |
||||||||
3900 | } |
||||||||
3901 | |||||||||
3902 | while (true) { |
||||||||
3903 | if ($this->gdimg_source) { |
||||||||
3904 | $this->DebugMessage('Not using EXIF thumbnail data because $this->gdimg_source is already set', __FILE__, __LINE__); |
||||||||
3905 | break; |
||||||||
3906 | } |
||||||||
3907 | if (!$this->exif_thumbnail_data) { |
||||||||
3908 | $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__); |
||||||||
3909 | break; |
||||||||
3910 | } |
||||||||
3911 | |||||||||
3912 | if (!$this->config_use_exif_thumbnail_for_speed) { |
||||||||
3913 | $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__); |
||||||||
3914 | break; |
||||||||
3915 | } |
||||||||
3916 | if ((0 != $this->thumbnailCropX) || (0 != $this->thumbnailCropY)) { |
||||||||
3917 | $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled (' . $this->thumbnailCropX . ',' . $this->thumbnailCropY . ')', __FILE__, __LINE__); |
||||||||
3918 | break; |
||||||||
3919 | } |
||||||||
3920 | if (($this->w > $this->exif_thumbnail_width) || ($this->h > $this->exif_thumbnail_height)) { |
||||||||
3921 | $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small (' . $this->exif_thumbnail_width . 'x' . $this->exif_thumbnail_height . ' vs ' . $this->w . 'x' . $this->h . ')', __FILE__, __LINE__); |
||||||||
3922 | break; |
||||||||
3923 | } |
||||||||
3924 | $source_ar = $this->source_width / $this->source_height; |
||||||||
3925 | $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height; |
||||||||
3926 | if (number_format($source_ar, 2) != number_format($exif_ar, 2)) { |
||||||||
3927 | $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar (' . $source_ar . ' != ' . $exif_ar . ')', __FILE__, __LINE__); |
||||||||
3928 | break; |
||||||||
3929 | } |
||||||||
3930 | |||||||||
3931 | // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image |
||||||||
3932 | $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__); |
||||||||
3933 | |||||||||
3934 | if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { |
||||||||
3935 | $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__); |
||||||||
3936 | $this->gdimg_source = $gdimg_exif_temp; |
||||||||
3937 | $this->source_width = $this->exif_thumbnail_width; |
||||||||
3938 | $this->source_height = $this->exif_thumbnail_height; |
||||||||
3939 | $this->thumbnailCropW = $this->source_width; |
||||||||
3940 | $this->thumbnailCropH = $this->source_height; |
||||||||
3941 | |||||||||
3942 | return true; |
||||||||
3943 | } |
||||||||
3944 | $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__); |
||||||||
3945 | |||||||||
3946 | break; |
||||||||
3947 | } |
||||||||
3948 | |||||||||
3949 | if (!$this->gdimg_source) { |
||||||||
3950 | $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__); |
||||||||
3951 | |||||||||
3952 | $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__); |
||||||||
3953 | |||||||||
3954 | $imageHeader = ''; |
||||||||
3955 | $gd_info = gd_info(); |
||||||||
3956 | $GDreadSupport = false; |
||||||||
3957 | switch (@$this->getimagesizeinfo[2]) { |
||||||||
3958 | case 1: |
||||||||
3959 | $imageHeader = 'Content-Type: image/gif'; |
||||||||
3960 | $GDreadSupport = (bool)@$gd_info['GIF Read Support']; |
||||||||
3961 | break; |
||||||||
3962 | case 2: |
||||||||
3963 | $imageHeader = 'Content-Type: image/jpeg'; |
||||||||
3964 | $GDreadSupport = (bool)@$gd_info['JPG Support']; |
||||||||
3965 | break; |
||||||||
3966 | case 3: |
||||||||
3967 | $imageHeader = 'Content-Type: image/png'; |
||||||||
3968 | $GDreadSupport = (bool)@$gd_info['PNG Support']; |
||||||||
3969 | break; |
||||||||
3970 | } |
||||||||
3971 | if ($imageHeader) { |
||||||||
3972 | // cannot create image for whatever reason (maybe imagecreatefromjpeg et al are not available?) |
||||||||
3973 | // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit |
||||||||
3974 | if ($this->config_error_die_on_source_failure) { |
||||||||
3975 | $errormessages = []; |
||||||||
3976 | $errormessages[] = 'All attempts to create GD image source failed.'; |
||||||||
3977 | if ($this->fatalerror) { |
||||||||
3978 | $errormessages[] = $this->fatalerror; |
||||||||
3979 | } |
||||||||
3980 | if ($this->issafemode) { |
||||||||
3981 | $errormessages[] = 'Safe Mode enabled, therefore ImageMagick is unavailable. (disable Safe Mode if possible)'; |
||||||||
3982 | } elseif (!$this->ImageMagickVersion()) { |
||||||||
3983 | $errormessages[] = 'ImageMagick is not installed (it is highly recommended that you install it).'; |
||||||||
3984 | } |
||||||||
3985 | if ($this->SourceImageIsTooLarge($this->getimagesizeinfo[0], $this->getimagesizeinfo[1])) { |
||||||||
3986 | $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0); |
||||||||
3987 | $errormessages[] = 'Source image is too large (' . $this->getimagesizeinfo[0] . 'x' . $this->getimagesizeinfo[1] . ' = ' . number_format($this->getimagesizeinfo[0] * $this->getimagesizeinfo[1] / 1000000, 1) . 'Mpx, max=' . number_format( |
||||||||
3988 | $this->config_max_source_pixels / 1000000, |
||||||||
3989 | 1 |
||||||||
3990 | ) . 'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least ' . ceil(($memory_get_usage + (5 * $this->getimagesizeinfo[0] * $this->getimagesizeinfo[1])) / 1048576) . 'M).'; |
||||||||
3991 | } elseif (!$GDreadSupport) { |
||||||||
3992 | $errormessages[] = 'GD does not have read support for "' . $imageHeader . '".'; |
||||||||
3993 | } else { |
||||||||
3994 | $errormessages[] = 'Source image probably corrupt.'; |
||||||||
3995 | } |
||||||||
3996 | $this->ErrorImage(implode("\n", $errormessages)); |
||||||||
3997 | } else { |
||||||||
3998 | $this->DebugMessage( |
||||||||
3999 | 'All attempts to create GD image source failed (' . (ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD' : ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "' |
||||||||
4000 | . $imageHeader |
||||||||
4001 | . '"')) . '), cannot generate thumbnail' |
||||||||
4002 | ); |
||||||||
4003 | //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__); |
||||||||
4004 | //if (!$this->phpThumbDebug) { |
||||||||
4005 | // header($imageHeader); |
||||||||
4006 | // echo $this->rawImageData; |
||||||||
4007 | // exit; |
||||||||
4008 | //} |
||||||||
4009 | return false; |
||||||||
4010 | } |
||||||||
4011 | } |
||||||||
4012 | |||||||||
4013 | //switch (substr($this->rawImageData, 0, 2)) { |
||||||||
4014 | // case 'BM': |
||||||||
4015 | switch (@$this->getimagesizeinfo[2]) { |
||||||||
4016 | case 6: |
||||||||
4017 | ob_start(); |
||||||||
4018 | if (!@require_once __DIR__ . '/phpthumb.bmp.php') { |
||||||||
4019 | ob_end_clean(); |
||||||||
4020 | |||||||||
4021 | return $this->ErrorImage('include_once(' . __DIR__ . '/phpthumb.bmp.php) failed'); |
||||||||
4022 | } |
||||||||
4023 | ob_end_clean(); |
||||||||
4024 | if ($fp = @fopen($this->sourceFilename, 'rb')) { |
||||||||
4025 | $this->rawImageData = ''; |
||||||||
4026 | while (!feof($fp)) { |
||||||||
4027 | $this->rawImageData .= fread($fp, 32768); |
||||||||
4028 | } |
||||||||
4029 | fclose($fp); |
||||||||
4030 | } |
||||||||
4031 | $phpthumb_bmp = new phpthumb_bmp(); |
||||||||
4032 | $this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, phpthumb_functions::gd_version() >= 2.0); |
||||||||
4033 | unset($phpthumb_bmp); |
||||||||
4034 | if ($this->gdimg_source) { |
||||||||
4035 | $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__); |
||||||||
4036 | } else { |
||||||||
4037 | return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed'); |
||||||||
4038 | } |
||||||||
4039 | break; |
||||||||
4040 | //} |
||||||||
4041 | //switch (substr($this->rawImageData, 0, 4)) { |
||||||||
4042 | // case 'II'."\x2A\x00": |
||||||||
4043 | // case 'MM'."\x00\x2A": |
||||||||
4044 | case 7: |
||||||||
4045 | case 8: |
||||||||
4046 | return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it'); |
||||||||
4047 | break; |
||||||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||||||
4048 | //case "\xD7\xCD\xC6\x9A": |
||||||||
4049 | // return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); |
||||||||
4050 | // break; |
||||||||
4051 | } |
||||||||
4052 | |||||||||
4053 | if (!$this->gdimg_source) { |
||||||||
4054 | if ($this->rawImageData) { |
||||||||
4055 | $HeaderFourBytes = mb_substr($this->rawImageData, 0, 4); |
||||||||
4056 | } elseif ($this->sourceFilename) { |
||||||||
4057 | if ($fp = @fopen($this->sourceFilename, 'rb')) { |
||||||||
4058 | $HeaderFourBytes = fread($fp, 4); |
||||||||
4059 | fclose($fp); |
||||||||
4060 | } else { |
||||||||
4061 | return $this->ErrorImage('failed to open "' . $this->sourceFilename . '" SourceImageToGD() [' . __LINE__ . ']'); |
||||||||
4062 | } |
||||||||
4063 | } else { |
||||||||
4064 | return $this->ErrorImage('Unable to create image, neither filename nor image data suppplied in SourceImageToGD() [' . __LINE__ . ']'); |
||||||||
4065 | } |
||||||||
4066 | if (!$this->ImageMagickVersion() && !phpthumb_functions::gd_version()) { |
||||||||
4067 | return $this->ErrorImage('Neither GD nor ImageMagick seem to be installed on this server. At least one (preferably GD), or better both, MUST be installed for phpThumb to work.'); |
||||||||
4068 | } elseif ("\xD7\xCD\xC6\x9A" === $HeaderFourBytes) { // WMF |
||||||||
4069 | return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it'); |
||||||||
4070 | } elseif ('%PDF' === $HeaderFourBytes) { // "%PDF" |
||||||||
4071 | return $this->ErrorImage( |
||||||||
4072 | $this->ImageMagickVersion() ? 'ImageMagick and GhostScript are both required for PDF source images; GhostScript may not be properly configured' : 'ImageMagick and/or GhostScript are unavailable and phpThumb() does not support PDF source images without them' |
||||||||
4073 | ); |
||||||||
4074 | } elseif ("\xFF\xD8\xFF" === mb_substr($HeaderFourBytes, 0, 3)) { // JPEG |
||||||||
4075 | return $this->ErrorImage('Image (JPEG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); |
||||||||
4076 | } elseif ('%PNG' === $HeaderFourBytes) { // "%PNG" |
||||||||
4077 | return $this->ErrorImage('Image (PNG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); |
||||||||
4078 | } elseif ('GIF' === mb_substr($HeaderFourBytes, 0, 3)) { // GIF |
||||||||
4079 | return $this->ErrorImage('Image (GIF) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting'); |
||||||||
4080 | } |
||||||||
4081 | |||||||||
4082 | return $this->ErrorImage('Unknown image type identified by "' . $HeaderFourBytes . '" (' . phpthumb_functions::HexCharDisplay($HeaderFourBytes) . ') in SourceImageToGD() [' . __LINE__ . ']'); |
||||||||
4083 | } |
||||||||
4084 | } |
||||||||
4085 | |||||||||
4086 | if (!$this->gdimg_source) { |
||||||||
4087 | if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) { |
||||||||
4088 | $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__); |
||||||||
4089 | $this->gdimg_source = $gdimg_exif_temp; |
||||||||
4090 | // override allow-enlarging setting if EXIF thumbnail is the only source available |
||||||||
4091 | // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size |
||||||||
4092 | $this->aoe = true; |
||||||||
4093 | |||||||||
4094 | return true; |
||||||||
4095 | } |
||||||||
4096 | |||||||||
4097 | return false; |
||||||||
4098 | } |
||||||||
4099 | |||||||||
4100 | $this->source_width = imagesx($this->gdimg_source); |
||||||||
4101 | $this->source_height = imagesy($this->gdimg_source); |
||||||||
4102 | |||||||||
4103 | return true; |
||||||||
4104 | } |
||||||||
4105 | |||||||||
4106 | /** |
||||||||
4107 | * @param $var |
||||||||
4108 | * @return string|void |
||||||||
4109 | */ |
||||||||
4110 | public function phpThumbDebugVarDump($var) |
||||||||
4111 | { |
||||||||
4112 | if (null === $var) { |
||||||||
4113 | return 'NULL'; |
||||||||
4114 | } elseif (is_bool($var)) { |
||||||||
4115 | return ($var ? 'TRUE' : 'FALSE'); |
||||||||
4116 | } elseif (is_string($var)) { |
||||||||
4117 | return 'string(' . mb_strlen($var) . ')' . str_repeat(' ', max(0, 3 - mb_strlen(mb_strlen($var)))) . ' "' . $var . '"'; |
||||||||
4118 | } elseif (is_int($var)) { |
||||||||
4119 | return 'integer ' . $var; |
||||||||
4120 | } elseif (is_float($var)) { |
||||||||
4121 | return 'float ' . $var; |
||||||||
4122 | } elseif (is_array($var)) { |
||||||||
4123 | ob_start(); |
||||||||
4124 | var_dump($var); |
||||||||
0 ignored issues
–
show
|
|||||||||
4125 | $vardumpoutput = ob_get_contents(); |
||||||||
4126 | ob_end_clean(); |
||||||||
4127 | |||||||||
4128 | return strtr($vardumpoutput, "\n\r\t", ' '); |
||||||||
4129 | } |
||||||||
4130 | |||||||||
4131 | return gettype($var); |
||||||||
4132 | } |
||||||||
4133 | |||||||||
4134 | /** |
||||||||
4135 | * @param string $level |
||||||||
4136 | * @return bool |
||||||||
4137 | */ |
||||||||
4138 | public function phpThumbDebug($level = '') |
||||||||
4139 | { |
||||||||
4140 | if ($level && ($this->phpThumbDebug !== $level)) { |
||||||||
4141 | return true; |
||||||||
4142 | } |
||||||||
4143 | if ($this->config_disable_debug) { |
||||||||
4144 | return $this->ErrorImage('phpThumbDebug disabled'); |
||||||||
4145 | } |
||||||||
4146 | |||||||||
4147 | $FunctionsExistance = [ |
||||||||
4148 | 'exif_thumbnail', |
||||||||
4149 | 'gd_info', |
||||||||
4150 | 'image_type_to_mime_type', |
||||||||
4151 | 'getimagesize', |
||||||||
4152 | 'imagecopyresampled', |
||||||||
4153 | 'imagecopyresized', |
||||||||
4154 | 'imagecreate', |
||||||||
4155 | 'imagecreatefromstring', |
||||||||
4156 | 'imagecreatetruecolor', |
||||||||
4157 | 'imageistruecolor', |
||||||||
4158 | 'imagerotate', |
||||||||
4159 | 'imagetypes', |
||||||||
4160 | 'version_compare', |
||||||||
4161 | 'imagecreatefromgif', |
||||||||
4162 | 'imagecreatefromjpeg', |
||||||||
4163 | 'imagecreatefrompng', |
||||||||
4164 | 'imagecreatefromwbmp', |
||||||||
4165 | 'imagecreatefromxbm', |
||||||||
4166 | 'imagecreatefromxpm', |
||||||||
4167 | 'imagecreatefromstring', |
||||||||
4168 | 'imagecreatefromgd', |
||||||||
4169 | 'imagecreatefromgd2', |
||||||||
4170 | 'imagecreatefromgd2part', |
||||||||
4171 | 'imagejpeg', |
||||||||
4172 | 'imagegif', |
||||||||
4173 | 'imagepng', |
||||||||
4174 | 'imagewbmp', |
||||||||
4175 | ]; |
||||||||
4176 | $ParameterNames = [ |
||||||||
4177 | 'src', |
||||||||
4178 | 'new', |
||||||||
4179 | 'w', |
||||||||
4180 | 'h', |
||||||||
4181 | 'f', |
||||||||
4182 | 'q', |
||||||||
4183 | 'sx', |
||||||||
4184 | 'sy', |
||||||||
4185 | 'sw', |
||||||||
4186 | 'sh', |
||||||||
4187 | 'far', |
||||||||
4188 | 'bg', |
||||||||
4189 | 'bc', |
||||||||
4190 | 'file', |
||||||||
4191 | 'goto', |
||||||||
4192 | 'err', |
||||||||
4193 | 'xto', |
||||||||
4194 | 'ra', |
||||||||
4195 | 'ar', |
||||||||
4196 | 'aoe', |
||||||||
4197 | 'iar', |
||||||||
4198 | 'maxb', |
||||||||
4199 | ]; |
||||||||
4200 | $ConfigVariableNames = [ |
||||||||
4201 | 'document_root', |
||||||||
4202 | 'temp_directory', |
||||||||
4203 | 'output_format', |
||||||||
4204 | 'output_maxwidth', |
||||||||
4205 | 'output_maxheight', |
||||||||
4206 | 'error_message_image_default', |
||||||||
4207 | 'error_bgcolor', |
||||||||
4208 | 'error_textcolor', |
||||||||
4209 | 'error_fontsize', |
||||||||
4210 | 'error_die_on_error', |
||||||||
4211 | 'error_silent_die_on_error', |
||||||||
4212 | 'error_die_on_source_failure', |
||||||||
4213 | 'nohotlink_enabled', |
||||||||
4214 | 'nohotlink_valid_domains', |
||||||||
4215 | 'nohotlink_erase_image', |
||||||||
4216 | 'nohotlink_text_message', |
||||||||
4217 | 'nooffsitelink_enabled', |
||||||||
4218 | 'nooffsitelink_valid_domains', |
||||||||
4219 | 'nooffsitelink_require_refer', |
||||||||
4220 | 'nooffsitelink_erase_image', |
||||||||
4221 | 'nooffsitelink_text_message', |
||||||||
4222 | 'high_security_enabled', |
||||||||
4223 | 'allow_src_above_docroot', |
||||||||
4224 | 'allow_src_above_phpthumb', |
||||||||
4225 | 'max_source_pixels', |
||||||||
4226 | 'use_exif_thumbnail_for_speed', |
||||||||
4227 | 'border_hexcolor', |
||||||||
4228 | 'background_hexcolor', |
||||||||
4229 | 'ttf_directory', |
||||||||
4230 | 'disable_pathinfo_parsing', |
||||||||
4231 | 'disable_imagecopyresampled', |
||||||||
4232 | ]; |
||||||||
4233 | $OtherVariableNames = [ |
||||||||
4234 | 'phpThumbDebug', |
||||||||
4235 | 'thumbnailQuality', |
||||||||
4236 | 'thumbnailFormat', |
||||||||
4237 | 'gdimg_output', |
||||||||
4238 | 'gdimg_source', |
||||||||
4239 | 'sourceFilename', |
||||||||
4240 | 'source_width', |
||||||||
4241 | 'source_height', |
||||||||
4242 | 'thumbnailCropX', |
||||||||
4243 | 'thumbnailCropY', |
||||||||
4244 | 'thumbnailCropW', |
||||||||
4245 | 'thumbnailCropH', |
||||||||
4246 | 'exif_thumbnail_width', |
||||||||
4247 | 'exif_thumbnail_height', |
||||||||
4248 | 'exif_thumbnail_type', |
||||||||
4249 | 'thumbnail_width', |
||||||||
4250 | 'thumbnail_height', |
||||||||
4251 | 'thumbnail_image_width', |
||||||||
4252 | 'thumbnail_image_height', |
||||||||
4253 | ]; |
||||||||
4254 | |||||||||
4255 | $DebugOutput = []; |
||||||||
4256 | $DebugOutput[] = 'phpThumb() version = ' . $this->phpthumb_version; |
||||||||
4257 | $DebugOutput[] = 'PHP_VERSION = ' . @PHP_VERSION; |
||||||||
4258 | $DebugOutput[] = 'PHP_OS = ' . PHP_OS; |
||||||||
4259 | $DebugOutput[] = '$_SERVER[SERVER_SOFTWARE] = ' . @$_SERVER['SERVER_SOFTWARE']; |
||||||||
4260 | $DebugOutput[] = '__FILE__ = ' . __FILE__; |
||||||||
4261 | $DebugOutput[] = 'realpath(.) = ' . @realpath('.'); |
||||||||
0 ignored issues
–
show
Are you sure
@realpath('.') of type false|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
4262 | $DebugOutput[] = '$_SERVER[PHP_SELF] = ' . @$_SERVER['PHP_SELF']; |
||||||||
4263 | $DebugOutput[] = '$_SERVER[HOST_NAME] = ' . @$_SERVER['HOST_NAME']; |
||||||||
4264 | $DebugOutput[] = '$_SERVER[HTTP_REFERER] = ' . @\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER'); |
||||||||
4265 | $DebugOutput[] = '$_SERVER[QUERY_STRING] = ' . @$_SERVER['QUERY_STRING']; |
||||||||
4266 | $DebugOutput[] = '$_SERVER[PATH_INFO] = ' . @$_SERVER['PATH_INFO']; |
||||||||
4267 | $DebugOutput[] = '$_SERVER[DOCUMENT_ROOT] = ' . @$_SERVER['DOCUMENT_ROOT']; |
||||||||
4268 | $DebugOutput[] = 'getenv(DOCUMENT_ROOT) = ' . @getenv('DOCUMENT_ROOT'); |
||||||||
4269 | $DebugOutput[] = ''; |
||||||||
4270 | |||||||||
4271 | $DebugOutput[] = 'get_magic_quotes_gpc() = ' . $this->phpThumbDebugVarDump(@get_magic_quotes_gpc()); |
||||||||
4272 | $DebugOutput[] = 'get_magic_quotes_runtime() = ' . $this->phpThumbDebugVarDump(@get_magic_quotes_runtime()); |
||||||||
4273 | $DebugOutput[] = 'error_reporting() = ' . $this->phpThumbDebugVarDump(error_reporting()); |
||||||||
4274 | $DebugOutput[] = 'ini_get(error_reporting) = ' . $this->phpThumbDebugVarDump(@ini_get('error_reporting')); |
||||||||
4275 | $DebugOutput[] = 'ini_get(display_errors) = ' . $this->phpThumbDebugVarDump(@ini_get('display_errors')); |
||||||||
4276 | $DebugOutput[] = 'ini_get(allow_url_fopen) = ' . $this->phpThumbDebugVarDump(@ini_get('allow_url_fopen')); |
||||||||
4277 | $DebugOutput[] = 'ini_get(disable_functions) = ' . $this->phpThumbDebugVarDump(@ini_get('disable_functions')); |
||||||||
4278 | $DebugOutput[] = 'get_cfg_var(disable_functions) = ' . $this->phpThumbDebugVarDump(@get_cfg_var('disable_functions')); |
||||||||
4279 | $DebugOutput[] = 'ini_get(safe_mode) = ' . $this->phpThumbDebugVarDump(@ini_get('safe_mode')); |
||||||||
4280 | $DebugOutput[] = 'ini_get(open_basedir) = ' . $this->phpThumbDebugVarDump(@ini_get('open_basedir')); |
||||||||
4281 | $DebugOutput[] = 'ini_get(max_execution_time) = ' . $this->phpThumbDebugVarDump(@ini_get('max_execution_time')); |
||||||||
4282 | $DebugOutput[] = 'ini_get(memory_limit) = ' . $this->phpThumbDebugVarDump(@ini_get('memory_limit')); |
||||||||
4283 | $DebugOutput[] = 'get_cfg_var(memory_limit) = ' . $this->phpThumbDebugVarDump(@get_cfg_var('memory_limit')); |
||||||||
4284 | $DebugOutput[] = 'memory_get_usage() = ' . (function_exists('memory_get_usage') ? $this->phpThumbDebugVarDump(@memory_get_usage()) : 'n/a'); |
||||||||
4285 | $DebugOutput[] = ''; |
||||||||
4286 | |||||||||
4287 | $DebugOutput[] = '$this->config_prefer_imagemagick = ' . $this->phpThumbDebugVarDump($this->config_prefer_imagemagick); |
||||||||
4288 | $DebugOutput[] = '$this->config_imagemagick_path = ' . $this->phpThumbDebugVarDump($this->config_imagemagick_path); |
||||||||
4289 | $DebugOutput[] = '$this->ImageMagickWhichConvert() = ' . $this->ImageMagickWhichConvert(); |
||||||||
4290 | $IMpathUsed = ($this->config_imagemagick_path ?: $this->ImageMagickWhichConvert()); |
||||||||
4291 | $DebugOutput[] = '[actual ImageMagick path used] = ' . $this->phpThumbDebugVarDump($IMpathUsed); |
||||||||
4292 | $DebugOutput[] = 'file_exists([actual ImageMagick path used]) = ' . $this->phpThumbDebugVarDump(@file_exists($IMpathUsed)); |
||||||||
4293 | $DebugOutput[] = 'ImageMagickVersion(false) = ' . $this->ImageMagickVersion(false); |
||||||||
4294 | $DebugOutput[] = 'ImageMagickVersion(true) = ' . $this->ImageMagickVersion(true); |
||||||||
4295 | $DebugOutput[] = ''; |
||||||||
4296 | |||||||||
4297 | $DebugOutput[] = '$this->config_cache_directory = ' . $this->phpThumbDebugVarDump($this->config_cache_directory); |
||||||||
4298 | $DebugOutput[] = '$this->config_cache_directory_depth = ' . $this->phpThumbDebugVarDump($this->config_cache_directory_depth); |
||||||||
4299 | $DebugOutput[] = '$this->config_cache_disable_warning = ' . $this->phpThumbDebugVarDump($this->config_cache_disable_warning); |
||||||||
4300 | $DebugOutput[] = '$this->config_cache_maxage = ' . $this->phpThumbDebugVarDump($this->config_cache_maxage); |
||||||||
4301 | $DebugOutput[] = '$this->config_cache_maxsize = ' . $this->phpThumbDebugVarDump($this->config_cache_maxsize); |
||||||||
4302 | $DebugOutput[] = '$this->config_cache_maxfiles = ' . $this->phpThumbDebugVarDump($this->config_cache_maxfiles); |
||||||||
4303 | $DebugOutput[] = '$this->config_cache_force_passthru = ' . $this->phpThumbDebugVarDump($this->config_cache_force_passthru); |
||||||||
4304 | $DebugOutput[] = '$this->cache_filename = ' . $this->phpThumbDebugVarDump($this->cache_filename); |
||||||||
4305 | $DebugOutput[] = 'is_readable($this->config_cache_directory) = ' . $this->phpThumbDebugVarDump(@is_readable($this->config_cache_directory)); |
||||||||
4306 | $DebugOutput[] = 'is_writable($this->config_cache_directory) = ' . $this->phpThumbDebugVarDump(@is_writable($this->config_cache_directory)); |
||||||||
4307 | $DebugOutput[] = 'is_readable($this->cache_filename) = ' . $this->phpThumbDebugVarDump(@is_readable($this->cache_filename)); |
||||||||
4308 | $DebugOutput[] = 'is_writable($this->cache_filename) = ' . (@file_exists($this->cache_filename) ? $this->phpThumbDebugVarDump(@is_writable($this->cache_filename)) : 'n/a'); |
||||||||
4309 | $DebugOutput[] = ''; |
||||||||
4310 | |||||||||
4311 | foreach ($ConfigVariableNames as $varname) { |
||||||||
4312 | $varname = 'config_' . $varname; |
||||||||
4313 | $value = $this->$varname; |
||||||||
4314 | $DebugOutput[] = '$this->' . str_pad($varname, 37, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4315 | } |
||||||||
4316 | $DebugOutput[] = ''; |
||||||||
4317 | foreach ($OtherVariableNames as $varname) { |
||||||||
4318 | $value = $this->$varname; |
||||||||
4319 | $DebugOutput[] = '$this->' . str_pad($varname, 27, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4320 | } |
||||||||
4321 | $DebugOutput[] = 'strlen($this->rawImageData) = ' . mb_strlen(@$this->rawImageData); |
||||||||
4322 | $DebugOutput[] = 'strlen($this->exif_thumbnail_data) = ' . mb_strlen(@$this->exif_thumbnail_data); |
||||||||
4323 | $DebugOutput[] = ''; |
||||||||
4324 | |||||||||
4325 | foreach ($ParameterNames as $varname) { |
||||||||
4326 | $value = $this->$varname; |
||||||||
4327 | $DebugOutput[] = '$this->' . str_pad($varname, 4, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4328 | } |
||||||||
4329 | $DebugOutput[] = ''; |
||||||||
4330 | |||||||||
4331 | foreach ($FunctionsExistance as $functionname) { |
||||||||
4332 | $DebugOutput[] = 'builtin_function_exists(' . $functionname . ')' . str_repeat(' ', 23 - mb_strlen($functionname)) . ' = ' . $this->phpThumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname)); |
||||||||
4333 | } |
||||||||
4334 | $DebugOutput[] = ''; |
||||||||
4335 | |||||||||
4336 | $gd_info = gd_info(); |
||||||||
4337 | foreach ($gd_info as $key => $value) { |
||||||||
4338 | $DebugOutput[] = 'gd_info.' . str_pad($key, 34, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4339 | } |
||||||||
4340 | $DebugOutput[] = ''; |
||||||||
4341 | |||||||||
4342 | $exif_info = phpthumb_functions::exif_info(); |
||||||||
4343 | foreach ($exif_info as $key => $value) { |
||||||||
4344 | $DebugOutput[] = 'exif_info.' . str_pad($key, 26, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4345 | } |
||||||||
4346 | $DebugOutput[] = ''; |
||||||||
4347 | |||||||||
4348 | if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) { |
||||||||
4349 | foreach ($ApacheLookupURIarray as $key => $value) { |
||||||||
4350 | $DebugOutput[] = 'ApacheLookupURIarray.' . str_pad($key, 15, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); |
||||||||
4351 | } |
||||||||
4352 | } else { |
||||||||
4353 | $DebugOutput[] = 'ApacheLookupURIarray() -- FAILED'; |
||||||||
4354 | } |
||||||||
4355 | $DebugOutput[] = ''; |
||||||||
4356 | |||||||||
4357 | if (isset($_GET) && is_array($_GET)) { |
||||||||
4358 | foreach ($_GET as $key => $value) { |
||||||||
4359 | $DebugOutput[] = '$_GET[' . $key . ']' . str_repeat(' ', 30 - mb_strlen($key)) . '= ' . $this->phpThumbDebugVarDump($value); |
||||||||
4360 | } |
||||||||
4361 | } |
||||||||
4362 | if (isset($_POST) && is_array($_POST)) { |
||||||||
4363 | foreach ($_POST as $key => $value) { |
||||||||
4364 | $DebugOutput[] = '$_POST[' . $key . ']' . str_repeat(' ', 29 - mb_strlen($key)) . '= ' . $this->phpThumbDebugVarDump($value); |
||||||||
4365 | } |
||||||||
4366 | } |
||||||||
4367 | $DebugOutput[] = ''; |
||||||||
4368 | |||||||||
4369 | $DebugOutput[] = '$this->debugmessages:'; |
||||||||
4370 | foreach ($this->debugmessages as $errorstring) { |
||||||||
4371 | $DebugOutput[] = ' * ' . $errorstring; |
||||||||
4372 | } |
||||||||
4373 | $DebugOutput[] = ''; |
||||||||
4374 | |||||||||
4375 | $DebugOutput[] = '$this->debugtiming:'; |
||||||||
4376 | foreach ($this->debugtiming as $timestamp => $timingstring) { |
||||||||
4377 | $DebugOutput[] = ' * ' . $timestamp . ' ' . $timingstring; |
||||||||
4378 | } |
||||||||
4379 | $DebugOutput[] = ' * Total processing time: ' . number_format(max(array_keys($this->debugtiming)) - min(array_keys($this->debugtiming)), 6); |
||||||||
4380 | |||||||||
4381 | $this->f = (isset($_GET['f']) ? $_GET['f'] : $this->f); // debug modes 0-2 don't recognize text mode otherwise |
||||||||
4382 | |||||||||
4383 | return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500, true); |
||||||||
0 ignored issues
–
show
Are you sure the usage of
$this->ErrorImage(implod...utput), 700, 500, true) targeting phpthumb::ErrorImage() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||||
4384 | } |
||||||||
4385 | |||||||||
4386 | /** |
||||||||
4387 | * @param $text |
||||||||
4388 | * @return bool |
||||||||
4389 | */ |
||||||||
4390 | public function FatalError($text) |
||||||||
4391 | { |
||||||||
4392 | if (null === $this->fatalerror) { |
||||||||
4393 | $this->fatalerror = $text; |
||||||||
4394 | } |
||||||||
4395 | |||||||||
4396 | return true; |
||||||||
4397 | } |
||||||||
4398 | |||||||||
4399 | /** |
||||||||
4400 | * @param $text |
||||||||
4401 | * @param int $width |
||||||||
4402 | * @param int $height |
||||||||
4403 | * @param bool $forcedisplay |
||||||||
4404 | * @return bool |
||||||||
4405 | */ |
||||||||
4406 | public function ErrorImage($text, $width = 0, $height = 0, $forcedisplay = false) |
||||||||
4407 | { |
||||||||
4408 | $width = ($width ?: $this->config_error_image_width); |
||||||||
4409 | $height = ($height ?: $this->config_error_image_height); |
||||||||
4410 | |||||||||
4411 | $text = 'phpThumb() v' . $this->phpthumb_version . "\n" . 'http://phpthumb.sourceforge.net' . "\n\n" . ($this->config_disable_debug ? 'Error messages disabled.' |
||||||||
4412 | . "\n\n" |
||||||||
4413 | . 'edit phpThumb.config.php and (temporarily) set' |
||||||||
4414 | . "\n" |
||||||||
4415 | . '$PHPTHUMB_CONFIG[\'disable_debug\'] = false;' |
||||||||
4416 | . "\n" |
||||||||
4417 | . 'to view the details of this error' : $text); |
||||||||
4418 | |||||||||
4419 | $this->FatalError($text); |
||||||||
4420 | $this->DebugMessage($text, __FILE__, __LINE__); |
||||||||
4421 | $this->purgeTempFiles(); |
||||||||
4422 | if ($this->config_error_silent_die_on_error) { |
||||||||
4423 | exit; |
||||||||
0 ignored issues
–
show
|
|||||||||
4424 | } |
||||||||
4425 | if ($this->phpThumbDebug && !$forcedisplay) { |
||||||||
4426 | return false; |
||||||||
4427 | } |
||||||||
4428 | if (!$this->config_error_die_on_error && !$forcedisplay) { |
||||||||
4429 | return false; |
||||||||
4430 | } |
||||||||
4431 | if ($this->err || $this->config_error_message_image_default) { |
||||||||
4432 | // Show generic custom error image instead of error message |
||||||||
4433 | // for use on production sites where you don't want debug messages |
||||||||
4434 | if (('showerror' === $this->err) || $this->phpThumbDebug) { |
||||||||
4435 | // fall through and actually show error message even if default error image is set |
||||||||
4436 | } else { |
||||||||
4437 | header('Location: ' . ($this->err ?: $this->config_error_message_image_default)); |
||||||||
4438 | exit; |
||||||||
4439 | } |
||||||||
4440 | } |
||||||||
4441 | $this->setOutputFormat(); |
||||||||
4442 | if (!$this->thumbnailFormat || !$this->config_disable_debug || (phpthumb_functions::gd_version() < 1)) { |
||||||||
4443 | $this->thumbnailFormat = 'text'; |
||||||||
4444 | } |
||||||||
4445 | if ('text' === @$this->thumbnailFormat) { |
||||||||
4446 | // bypass all GD functions and output text error message |
||||||||
4447 | if (!headers_sent()) { |
||||||||
4448 | header('Content-type: text/plain'); |
||||||||
4449 | echo $text; |
||||||||
4450 | } else { |
||||||||
4451 | echo '<pre>' . htmlspecialchars($text, ENT_QUOTES | ENT_HTML5) . '</pre>'; |
||||||||
4452 | } |
||||||||
4453 | exit; |
||||||||
0 ignored issues
–
show
|
|||||||||
4454 | } |
||||||||
4455 | |||||||||
4456 | $FontWidth = imagefontwidth($this->config_error_fontsize); |
||||||||
4457 | $FontHeight = imagefontheight($this->config_error_fontsize); |
||||||||
4458 | |||||||||
4459 | $LinesOfText = explode("\n", @wordwrap($text, floor($width / $FontWidth), "\n", true)); |
||||||||
0 ignored issues
–
show
floor($width / $FontWidth) of type double is incompatible with the type integer expected by parameter $width of wordwrap() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
4460 | $height = max($height, count($LinesOfText) * $FontHeight); |
||||||||
4461 | |||||||||
4462 | $headers_file = ''; |
||||||||
4463 | $headers_line = ''; |
||||||||
4464 | if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=') |
||||||||
4465 | && headers_sent($headers_file, $headers_line)) { |
||||||||
0 ignored issues
–
show
$headers_line of type string is incompatible with the type integer expected by parameter $line of headers_sent() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
4466 | echo "\n" . '**Headers already sent in file "' . $headers_file . '" on line "' . $headers_line . '", dumping error message as text:**<br><pre>' . "\n\n" . $text . "\n" . '</pre>'; |
||||||||
4467 | } elseif (headers_sent()) { |
||||||||
4468 | echo "\n" . '**Headers already sent, dumping error message as text:**<br><pre>' . "\n\n" . $text . "\n" . '</pre>'; |
||||||||
4469 | } elseif ($gdimg_error = imagecreate($width, $height)) { |
||||||||
4470 | $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor, true); |
||||||||
4471 | $text_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true); |
||||||||
4472 | imagefilledrectangle($gdimg_error, 0, 0, $width, $height, $background_color); |
||||||||
4473 | $lineYoffset = 0; |
||||||||
4474 | foreach ($LinesOfText as $line) { |
||||||||
4475 | imagestring($gdimg_error, $this->config_error_fontsize, 2, $lineYoffset, $line, $text_color); |
||||||||
4476 | $lineYoffset += $FontHeight; |
||||||||
4477 | } |
||||||||
4478 | if (function_exists('imagetypes')) { |
||||||||
4479 | $imagetypes = imagetypes(); |
||||||||
4480 | if ($imagetypes & IMG_PNG) { |
||||||||
4481 | header('Content-Type: image/png'); |
||||||||
4482 | imagepng($gdimg_error); |
||||||||
4483 | } elseif ($imagetypes & IMG_GIF) { |
||||||||
4484 | header('Content-Type: image/gif'); |
||||||||
4485 | imagegif($gdimg_error); |
||||||||
4486 | } elseif ($imagetypes & IMG_JPG) { |
||||||||
4487 | header('Content-Type: image/jpeg'); |
||||||||
4488 | imagejpeg($gdimg_error); |
||||||||
4489 | } elseif ($imagetypes & IMG_WBMP) { |
||||||||
4490 | header('Content-Type: image/vnd.wap.wbmp'); |
||||||||
4491 | imagewbmp($gdimg_error); |
||||||||
4492 | } |
||||||||
4493 | } |
||||||||
4494 | imagedestroy($gdimg_error); |
||||||||
4495 | } |
||||||||
4496 | if (!headers_sent()) { |
||||||||
4497 | echo "\n" . '**Failed to send graphical error image, dumping error message as text:**<br>' . "\n\n" . $text; |
||||||||
4498 | } |
||||||||
4499 | exit; |
||||||||
0 ignored issues
–
show
|
|||||||||
4500 | } |
||||||||
4501 | |||||||||
4502 | /** |
||||||||
4503 | * @param $RawImageData |
||||||||
4504 | * @param bool $DieOnErrors |
||||||||
4505 | * @return bool|resource |
||||||||
4506 | */ |
||||||||
4507 | public function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors = false) |
||||||||
4508 | { |
||||||||
4509 | // there are serious bugs in the non-bundled versions of GD which may cause |
||||||||
4510 | // PHP to segfault when calling imagecreatefromstring() - avoid if at all possible |
||||||||
4511 | // when not using a bundled version of GD2 |
||||||||
4512 | if (!phpthumb_functions::gd_version()) { |
||||||||
4513 | if ($DieOnErrors) { |
||||||||
4514 | if (!headers_sent()) { |
||||||||
4515 | // base64-encoded error image in GIF format |
||||||||
4516 | $ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7'; |
||||||||
4517 | header('Content-Type: image/gif'); |
||||||||
4518 | echo base64_decode($ERROR_NOGD, true); |
||||||||
4519 | } else { |
||||||||
4520 | echo '*** ERROR: No PHP-GD support available ***'; |
||||||||
4521 | } |
||||||||
4522 | exit; |
||||||||
0 ignored issues
–
show
|
|||||||||
4523 | } |
||||||||
4524 | $this->DebugMessage('ImageCreateFromStringReplacement() failed: gd_version says "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); |
||||||||
4525 | |||||||||
4526 | return false; |
||||||||
4527 | } |
||||||||
4528 | if (phpthumb_functions::gd_is_bundled()) { |
||||||||
4529 | $this->DebugMessage('ImageCreateFromStringReplacement() calling built-in imagecreatefromstring()', __FILE__, __LINE__); |
||||||||
4530 | |||||||||
4531 | return @imagecreatefromstring($RawImageData); |
||||||||
0 ignored issues
–
show
|
|||||||||
4532 | } |
||||||||
4533 | if ($this->issafemode) { |
||||||||
4534 | $this->DebugMessage('ImageCreateFromStringReplacement() failed: cannot create temp file in SAFE_MODE', __FILE__, __LINE__); |
||||||||
4535 | |||||||||
4536 | return false; |
||||||||
4537 | } |
||||||||
4538 | |||||||||
4539 | switch (mb_substr($RawImageData, 0, 3)) { |
||||||||
4540 | case 'GIF': |
||||||||
4541 | $ICFSreplacementFunctionName = 'imagecreatefromgif'; |
||||||||
4542 | break; |
||||||||
4543 | case "\xFF\xD8\xFF": |
||||||||
4544 | $ICFSreplacementFunctionName = 'imagecreatefromjpeg'; |
||||||||
4545 | break; |
||||||||
4546 | case "\x89" . 'PN': |
||||||||
4547 | $ICFSreplacementFunctionName = 'imagecreatefrompng'; |
||||||||
4548 | break; |
||||||||
4549 | default: |
||||||||
4550 | $this->DebugMessage('ImageCreateFromStringReplacement() failed: unknown fileformat signature "' . phpthumb_functions::HexCharDisplay(mb_substr($RawImageData, 0, 3)) . '"', __FILE__, __LINE__); |
||||||||
4551 | |||||||||
4552 | return false; |
||||||||
4553 | break; |
||||||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||||||
4554 | } |
||||||||
4555 | $ErrorMessage = ''; |
||||||||
4556 | if ($tempnam = $this->phpThumb_tempnam()) { |
||||||||
4557 | if ($fp_tempnam = @fopen($tempnam, 'wb')) { |
||||||||
4558 | fwrite($fp_tempnam, $RawImageData); |
||||||||
4559 | fclose($fp_tempnam); |
||||||||
4560 | if (('imagecreatefromgif' === $ICFSreplacementFunctionName) |
||||||||
4561 | && !function_exists($ICFSreplacementFunctionName)) { |
||||||||
4562 | // Need to create from GIF file, but imagecreatefromgif does not exist |
||||||||
4563 | ob_start(); |
||||||||
4564 | if (!@require_once __DIR__ . '/phpthumb.gif.php') { |
||||||||
4565 | $ErrorMessage = 'Failed to include required file "' . __DIR__ . '/phpthumb.gif.php" in ' . __FILE__ . ' on line ' . __LINE__; |
||||||||
4566 | $this->DebugMessage($ErrorMessage, __FILE__, __LINE__); |
||||||||
4567 | } |
||||||||
4568 | ob_end_clean(); |
||||||||
4569 | // gif_loadFileToGDimageResource() cannot read from raw data, write to file first |
||||||||
4570 | if ($tempfilename = $this->phpThumb_tempnam()) { |
||||||||
4571 | if ($fp_tempfile = @fopen($tempfilename, 'wb')) { |
||||||||
4572 | fwrite($fp_tempfile, $RawImageData); |
||||||||
4573 | fclose($fp_tempfile); |
||||||||
4574 | $gdimg_source = gif_loadFileToGDimageResource($tempfilename); |
||||||||
4575 | $this->DebugMessage('gif_loadFileToGDimageResource(' . $tempfilename . ') completed', __FILE__, __LINE__); |
||||||||
4576 | $this->DebugMessage('deleting "' . $tempfilename . '"', __FILE__, __LINE__); |
||||||||
4577 | unlink($tempfilename); |
||||||||
4578 | |||||||||
4579 | return $gdimg_source; |
||||||||
0 ignored issues
–
show
|
|||||||||
4580 | } |
||||||||
4581 | $ErrorMessage = 'Failed to open tempfile in ' . __FILE__ . ' on line ' . __LINE__; |
||||||||
4582 | $this->DebugMessage($ErrorMessage, __FILE__, __LINE__); |
||||||||
4583 | } else { |
||||||||
4584 | $ErrorMessage = 'Failed to open generate tempfile name in ' . __FILE__ . ' on line ' . __LINE__; |
||||||||
4585 | $this->DebugMessage($ErrorMessage, __FILE__, __LINE__); |
||||||||
4586 | } |
||||||||
4587 | } elseif (function_exists($ICFSreplacementFunctionName) |
||||||||
4588 | && ($gdimg_source = @$ICFSreplacementFunctionName($tempnam))) { |
||||||||
4589 | // great |
||||||||
4590 | $this->DebugMessage($ICFSreplacementFunctionName . '(' . $tempnam . ') succeeded', __FILE__, __LINE__); |
||||||||
4591 | $this->DebugMessage('deleting "' . $tempnam . '"', __FILE__, __LINE__); |
||||||||
4592 | unlink($tempnam); |
||||||||
4593 | |||||||||
4594 | return $gdimg_source; |
||||||||
4595 | } else { |
||||||||
4596 | // GD functions not available, or failed to create image |
||||||||
4597 | $this->DebugMessage($ICFSreplacementFunctionName . '(' . $tempnam . ') ' . (function_exists($ICFSreplacementFunctionName) ? 'failed' : 'does not exist'), __FILE__, __LINE__); |
||||||||
4598 | if (isset($_GET['phpThumbDebug'])) { |
||||||||
4599 | $this->phpThumbDebug(); |
||||||||
4600 | } |
||||||||
4601 | } |
||||||||
4602 | } else { |
||||||||
4603 | $ErrorMessage = 'Failed to fopen(' . $tempnam . ', "wb") in ' . __FILE__ . ' on line ' . __LINE__ . "\n" . 'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php'; |
||||||||
4604 | if ($this->issafemode) { |
||||||||
4605 | $ErrorMessage = 'ImageCreateFromStringReplacement() failed in ' . __FILE__ . ' on line ' . __LINE__ . ': cannot create temp file in SAFE_MODE'; |
||||||||
4606 | } |
||||||||
4607 | $this->DebugMessage($ErrorMessage, __FILE__, __LINE__); |
||||||||
4608 | } |
||||||||
4609 | $this->DebugMessage('deleting "' . $tempnam . '"', __FILE__, __LINE__); |
||||||||
4610 | @unlink($tempnam); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
4611 | } else { |
||||||||
4612 | $ErrorMessage = 'Failed to generate phpThumb_tempnam() in ' . __FILE__ . ' on line ' . __LINE__ . "\n" . 'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php'; |
||||||||
4613 | if ($this->issafemode) { |
||||||||
4614 | $ErrorMessage = 'ImageCreateFromStringReplacement() failed in ' . __FILE__ . ' on line ' . __LINE__ . ': cannot create temp file in SAFE_MODE'; |
||||||||
4615 | } |
||||||||
4616 | } |
||||||||
4617 | if ($DieOnErrors && $ErrorMessage) { |
||||||||
4618 | return $this->ErrorImage($ErrorMessage); |
||||||||
4619 | } |
||||||||
4620 | |||||||||
4621 | return false; |
||||||||
4622 | } |
||||||||
4623 | |||||||||
4624 | /** |
||||||||
4625 | * @param $dst_im |
||||||||
4626 | * @param $src_im |
||||||||
4627 | * @param $dstX |
||||||||
4628 | * @param $dstY |
||||||||
4629 | * @param $srcX |
||||||||
4630 | * @param $srcY |
||||||||
4631 | * @param $dstW |
||||||||
4632 | * @param $dstH |
||||||||
4633 | * @param $srcW |
||||||||
4634 | * @param $srcH |
||||||||
4635 | * @return bool |
||||||||
4636 | */ |
||||||||
4637 | public function ImageResizeFunction(&$dst_im, &$src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) |
||||||||
4638 | { |
||||||||
4639 | $this->DebugMessage('ImageResizeFunction($o, $s, ' . $dstX . ', ' . $dstY . ', ' . $srcX . ', ' . $srcY . ', ' . $dstW . ', ' . $dstH . ', ' . $srcW . ', ' . $srcH . ')', __FILE__, __LINE__); |
||||||||
4640 | if (($dstW == $srcW) && ($dstH == $srcH)) { |
||||||||
4641 | return imagecopy($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH); |
||||||||
4642 | } |
||||||||
4643 | if (phpthumb_functions::gd_version() >= 2.0) { |
||||||||
4644 | if ($this->config_disable_imagecopyresampled) { |
||||||||
4645 | return phpthumb_functions::ImageCopyResampleBicubic($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); |
||||||||
4646 | } |
||||||||
4647 | |||||||||
4648 | return imagecopyresampled($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); |
||||||||
4649 | } |
||||||||
4650 | |||||||||
4651 | return imagecopyresized($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); |
||||||||
4652 | } |
||||||||
4653 | |||||||||
4654 | /** |
||||||||
4655 | * @return bool |
||||||||
4656 | */ |
||||||||
4657 | public function InitializeTempDirSetting() |
||||||||
4658 | { |
||||||||
4659 | $this->config_temp_directory = ($this->config_temp_directory ?: (function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : '')); // sys_get_temp_dir added in PHP v5.2.1 |
||||||||
4660 | $this->config_temp_directory = ($this->config_temp_directory ?: getenv('TMPDIR')); |
||||||||
4661 | $this->config_temp_directory = ($this->config_temp_directory ?: getenv('TMP')); |
||||||||
4662 | $this->config_temp_directory = ($this->config_temp_directory ?: ini_get('upload_tmp_dir')); |
||||||||
4663 | $this->config_temp_directory = $this->realPathSafe($this->config_temp_directory); |
||||||||
4664 | |||||||||
4665 | return true; |
||||||||
4666 | } |
||||||||
4667 | |||||||||
4668 | /** |
||||||||
4669 | * @return bool|null|string|string[] |
||||||||
4670 | */ |
||||||||
4671 | public function phpThumb_tempnam() |
||||||||
4672 | { |
||||||||
4673 | $this->InitializeTempDirSetting(); |
||||||||
4674 | $tempnam = $this->realPathSafe(tempnam($this->config_temp_directory, 'pThumb')); |
||||||||
4675 | $this->tempFilesToDelete[$tempnam] = $tempnam; |
||||||||
4676 | $this->DebugMessage('phpThumb_tempnam() returning "' . $tempnam . '"', __FILE__, __LINE__); |
||||||||
4677 | |||||||||
4678 | return $tempnam; |
||||||||
4679 | } |
||||||||
4680 | |||||||||
4681 | /** |
||||||||
4682 | * @param $message |
||||||||
4683 | * @param string $file |
||||||||
4684 | * @param string $line |
||||||||
4685 | * @return bool |
||||||||
4686 | */ |
||||||||
4687 | public function DebugMessage($message, $file = '', $line = '') |
||||||||
4688 | { |
||||||||
4689 | $this->debugmessages[] = $message . ($file ? ' in file "' . (basename($file) ?: $file) . '"' : '') . ($line ? ' on line ' . $line : ''); |
||||||||
4690 | |||||||||
4691 | return true; |
||||||||
4692 | } |
||||||||
4693 | |||||||||
4694 | /** |
||||||||
4695 | * @param $message |
||||||||
4696 | * @param string $file |
||||||||
4697 | * @param string $line |
||||||||
4698 | * @param int $timestamp |
||||||||
4699 | * @return bool |
||||||||
4700 | */ |
||||||||
4701 | public function DebugTimingMessage($message, $file = '', $line = '', $timestamp = 0) |
||||||||
4702 | { |
||||||||
4703 | if (!$timestamp) { |
||||||||
4704 | $timestamp = array_sum(explode(' ', microtime())); |
||||||||
4705 | } |
||||||||
4706 | $this->debugtiming[number_format($timestamp, 6, '.', '')] = ': ' . $message . ($file ? ' in file "' . (basename($file) ?: $file) . '"' : '') . ($line ? ' on line ' . $line : ''); |
||||||||
4707 | |||||||||
4708 | return true; |
||||||||
4709 | } |
||||||||
4710 | } |
||||||||
4711 |