Issues (807)

Security Analysis    not enabled

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

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

phpthumb/phpThumb.php (13 issues)

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.changelog.txt for recent changes           //
9
// See: phpthumb.readme.txt for usage instructions          //
10
//                                                         ///
11
//////////////////////////////////////////////////////////////
12
13
error_reporting(E_ALL);
14
ini_set('display_errors', '1');
15
16
// check for magic quotes in PHP < 7.4.0 (when these functions became deprecated)
17
if (version_compare(PHP_VERSION, '7.4.0', '<')) {
18
    ini_set('magic_quotes_runtime', '0');
19
    if (ini_get('magic_quotes_runtime')) {
20
        die('"magic_quotes_runtime" is set in php.ini, cannot run phpThumb with this enabled');
21
    }
22
}
23
// Set a default timezone if web server has not done already in php.ini
24
if (!ini_get('date.timezone') && function_exists('date_default_timezone_set')) { // PHP >= 5.1.0
25
    date_default_timezone_set('UTC');
26
}
27
$starttime = array_sum(explode(' ', microtime())); // could be called as microtime(true) for PHP 5.0.0+
28
29
// this script relies on the superglobal arrays, fake it here for old PHP versions
30
if (PHP_VERSION < '4.1.0') {
31
    $_SERVER = $HTTP_SERVER_VARS;
32
    $_GET    = $HTTP_GET_VARS;
33
}
34
35
function SendSaveAsFileHeaderIfNeeded($getimagesize = false)
36
{
37
    if (headers_sent()) {
38
        return false;
39
    }
40
    global $phpThumb;
41
    $downloadfilename = phpthumb_functions::SanitizeFilename(!empty($_GET['sia']) ? $_GET['sia'] : (!empty($_GET['down']) ? $_GET['down'] : 'phpThumb_generated_thumbnail.' . (!empty($_GET['f']) ? $_GET['f'] : 'jpg')));
42
    //if (empty($_GET['sia']) && empty($_GET['down']) && !empty($phpThumb->thumbnail_image_width) && !empty($phpThumb->thumbnail_image_height)) {
43
    if (empty($_GET['sia']) && empty($_GET['down']) && !empty($getimagesize[0]) && !empty($getimagesize[1])) {
44
        // if we know the output image dimensions we can generate a better default filename
45
        $downloadfilename = phpthumb_functions::SanitizeFilename((!empty($phpThumb->src) ? basename($phpThumb->src) : md5($phpThumb->rawImageData)) . '-' . intval($getimagesize[0]) . 'x' . intval($getimagesize[1]) . '.' . (!empty($_GET['f']) ? $_GET['f'] : 'jpg'));
46
    }
47
    if (!empty($downloadfilename)) {
48
        $phpThumb->DebugMessage('SendSaveAsFileHeaderIfNeeded() sending header: Content-Disposition: ' . (!empty($_GET['down']) ? 'attachment' : 'inline') . '; filename="' . $downloadfilename . '"', __FILE__, __LINE__);
49
        header('Content-Disposition: ' . (!empty($_GET['down']) ? 'attachment' : 'inline') . '; filename="' . $downloadfilename . '"');
50
    }
51
    return true;
52
}
53
54
function RedirectToCachedFile()
55
{
56
    global $phpThumb;
57
58
    $nice_cachefile = str_replace(DIRECTORY_SEPARATOR, '/', $phpThumb->cache_filename);
59
    $nice_docroot   = str_replace(DIRECTORY_SEPARATOR, '/', rtrim($phpThumb->config_document_root, '/\\'));
60
61
    $parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
62
63
    $nModified = filemtime($phpThumb->cache_filename);
64
65
    if ($phpThumb->config_nooffsitelink_enabled && !empty($_SERVER['HTTP_REFERER']) && !in_array(@$parsed_url['host'], $phpThumb->config_nooffsitelink_valid_domains)) {
66
        $phpThumb->DebugMessage(
67
            'Would have used cached (image/'
68
            . $phpThumb->thumbnailFormat
69
            . ') file "'
70
            . $phpThumb->cache_filename
71
            . '" (Last-Modified: '
72
            . gmdate('D, d M Y H:i:s', $nModified)
73
            . ' GMT), but skipping because $_SERVER[HTTP_REFERER] ('
74
            . @$_SERVER['HTTP_REFERER']
75
            . ') is not in $phpThumb->config_nooffsitelink_valid_domains ('
76
            . implode(';', $phpThumb->config_nooffsitelink_valid_domains)
77
            . ')',
78
            __FILE__,
79
            __LINE__
80
        );
81
    } elseif ($phpThumb->phpThumbDebug) {
82
        $phpThumb->DebugTimingMessage('skipped using cached image', __FILE__, __LINE__);
83
        $phpThumb->DebugMessage('Would have used cached file, but skipping due to phpThumbDebug', __FILE__, __LINE__);
84
        $phpThumb->DebugMessage('* Would have sent headers (1): Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT', __FILE__, __LINE__);
85
        if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
86
            $phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
0 ignored issues
show
Are you sure phpthumb_functions::Imag...Etype($getimagesize[2]) 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 ignore-type  annotation

86
            $phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: ' . /** @scrutinizer ignore-type */ phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
Loading history...
87
        }
88
        if (preg_match('#^' . preg_quote($nice_docroot) . '(.*)$#', $nice_cachefile, $matches)) {
89
            $phpThumb->DebugMessage('* Would have sent headers (3): Location: ' . dirname($matches[1]) . '/' . urlencode(basename($matches[1])), __FILE__, __LINE__);
90
        } else {
91
            $phpThumb->DebugMessage('* Would have sent data: file_get_contents(' . $phpThumb->cache_filename . ')', __FILE__, __LINE__);
92
        }
93
    } else {
94
        if (headers_sent()) {
95
            $phpThumb->ErrorImage('Headers already sent (' . basename(__FILE__) . ' line ' . __LINE__ . ')');
96
            exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
97
        }
98
        $getimagesize = @getimagesize($phpThumb->cache_filename);
99
        SendSaveAsFileHeaderIfNeeded($getimagesize);
100
101
        header('Pragma: private');
102
        header('Cache-Control: max-age=' . $phpThumb->getParameter('config_cache_maxage'));
103
        header('Expires: ' . date(DATE_RFC1123, time() + $phpThumb->getParameter('config_cache_maxage')));
104
        if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
105
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT');
106
            header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
107
            exit;
108
        }
109
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT');
110
        header('ETag: "' . md5_file($phpThumb->cache_filename) . '"');
111
        if (!empty($getimagesize[2])) {
112
            header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]));
113
        } elseif (preg_match('#\\.ico$#i', $phpThumb->cache_filename)) {
114
            header('Content-Type: image/x-icon');
115
        }
116
        header('Content-Length: ' . filesize($phpThumb->cache_filename));
117
        if (empty($phpThumb->config_cache_force_passthru) && preg_match('#^' . preg_quote($nice_docroot) . '(.*)$#', $nice_cachefile, $matches)) {
118
            header('Location: ' . dirname($matches[1]) . '/' . urlencode(basename($matches[1])));
119
        } else {
120
            echo file_get_contents($phpThumb->cache_filename);
121
        }
122
        exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
123
    }
124
    return true;
125
}
126
127
// instantiate a new phpThumb() object
128
ob_start();
129
if (!include_once __DIR__ . '/phpthumb.class.php') {
130
    ob_end_flush();
131
    die('failed to include_once("' . realpath(__DIR__ . '/phpthumb.class.php') . '")');
132
}
133
ob_end_clean();
134
$phpThumb = new phpThumb();
135
$phpThumb->DebugTimingMessage('phpThumb.php start', __FILE__, __LINE__, $starttime);
136
$phpThumb->setParameter('config_error_die_on_error', true);
137
138
if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
139
    set_time_limit(60);  // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
140
}
141
142
// phpThumbDebug[0] used to be here, but may reveal too much
143
// info when high_security_mode should be enabled (not set yet)
144
145
if (file_exists(__DIR__ . '/phpThumb.config.php')) {
146
    ob_start();
147
    if (include_once __DIR__ . '/phpThumb.config.php') {
148
        // great
149
    } else {
150
        ob_end_flush();
151
        $phpThumb->config_disable_debug = false; // otherwise error message won't print
152
        $phpThumb->ErrorImage('failed to include_once(' . __DIR__ . '/phpThumb.config.php) - realpath="' . realpath(__DIR__ . '/phpThumb.config.php') . '"');
153
    }
154
    ob_end_clean();
155
} elseif (file_exists(__DIR__ . '/phpThumb.config.php.default')) {
156
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
157
    $phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
158
} else {
159
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
160
    $phpThumb->ErrorImage('failed to include_once(' . __DIR__ . '/phpThumb.config.php) - realpath="' . realpath(__DIR__ . '/phpThumb.config.php') . '"');
161
}
162
163
if (!empty($PHPTHUMB_CONFIG)) {
164
    foreach ($PHPTHUMB_CONFIG as $key => $value) {
165
        $keyname = 'config_' . $key;
166
        $phpThumb->setParameter($keyname, $value);
167
        if (!preg_match('#(password|mysql)#i', $key)) {
168
            $phpThumb->DebugMessage('setParameter(' . $keyname . ', ' . $phpThumb->phpThumbDebugVarDump($value) . ')', __FILE__, __LINE__);
169
        }
170
    }
171
    if (!$phpThumb->config_disable_debug) {
172
        // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
173
        $_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, (int)$_GET['phpThumbDebug']) : 9);
174
        $phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
175
    }
176
} else {
177
    $phpThumb->DebugMessage('$PHPTHUMB_CONFIG is empty', __FILE__, __LINE__);
178
}
179
180
if (empty($phpThumb->config_disable_pathinfo_parsing) && (empty($_GET) || isset($_GET['phpThumbDebug'])) && !empty($_SERVER['PATH_INFO'])) {
181
    $_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);
182
183
    $args = explode(';', substr($_SERVER['PATH_INFO'], 1));
184
    $phpThumb->DebugMessage('PATH_INFO.$args set to (' . implode(')(', $args) . ')', __FILE__, __LINE__);
185
    if (!empty($args)) {
186
        $_GET['src'] = @$args[count($args) - 1];
187
        $phpThumb->DebugMessage('PATH_INFO."src" = "' . $_GET['src'] . '"', __FILE__, __LINE__);
188
        if (preg_match('#^new\=([a-z0-9]+)#i', $_GET['src'], $matches)) {
189
            unset($_GET['src']);
190
            $_GET['new'] = $matches[1];
191
        }
192
    }
193
    if (preg_match('#^([\d]*)x?([\d]*)$#i', @$args[count($args) - 2], $matches)) {
194
        $_GET['w'] = $matches[1];
195
        $_GET['h'] = $matches[2];
196
        $phpThumb->DebugMessage('PATH_INFO."w"x"h" set to "' . $_GET['w'] . '"x"' . $_GET['h'] . '"', __FILE__, __LINE__);
197
    }
198
    for ($i = 0; $i < count($args) - 2; $i++) {
199
        @list($key, $value) = explode('=', @$args[$i]);
200
        if (substr($key, -2) == '[]') {
201
            $array_key_name          = substr($key, 0, -2);
202
            $_GET[$array_key_name][] = $value;
203
            $phpThumb->DebugMessage('PATH_INFO."' . $array_key_name . '[]" = "' . $value . '"', __FILE__, __LINE__);
204
        } else {
205
            $_GET[$key] = $value;
206
            $phpThumb->DebugMessage('PATH_INFO."' . $key . '" = "' . $value . '"', __FILE__, __LINE__);
207
        }
208
    }
209
}
210
211
if (!empty($phpThumb->config_high_security_enabled)) {
212
    if (empty($_GET['hash'])) {
213
        $phpThumb->config_disable_debug = false; // otherwise error message won't print
214
        $phpThumb->ErrorImage('ERROR: missing hash');
215
    } elseif (phpthumb_functions::PasswordStrength($phpThumb->config_high_security_password) < 20) {
216
        $phpThumb->config_disable_debug = false; // otherwise error message won't print
217
        $phpThumb->ErrorImage('ERROR: $PHPTHUMB_CONFIG[high_security_password] is not complex enough');
218
    } elseif ($_GET['hash'] != md5(str_replace($phpThumb->config_high_security_url_separator . 'hash=' . $_GET['hash'], '', $_SERVER['QUERY_STRING']) . $phpThumb->config_high_security_password)) {
219
        header('HTTP/1.0 403 Forbidden');
220
        sleep(10); // deliberate delay to discourage password-guessing
221
        $phpThumb->ErrorImage('ERROR: invalid hash');
222
    }
223
}
224
225
////////////////////////////////////////////////////////////////
226
// Debug output, to try and help me diagnose problems
227
$phpThumb->DebugTimingMessage('phpThumbDebug[0]', __FILE__, __LINE__);
228
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '0')) {
229
    $phpThumb->phpThumbDebug();
230
}
231
////////////////////////////////////////////////////////////////
232
233
// check for magic quotes in PHP < 7.4.0 (when these functions became deprecated)
234
if (version_compare(PHP_VERSION, '7.4.0', '<')) {
235
    // returned the fixed string if the evil "magic_quotes_gpc" setting is on
236
    if (get_magic_quotes_gpc()) {
237
        // deprecated: 'err', 'file', 'goto',
238
        $RequestVarsToStripSlashes = ['src', 'wmf', 'down'];
239
        foreach ($RequestVarsToStripSlashes as $key) {
240
            if (isset($_GET[$key])) {
241
                if (is_string($_GET[$key])) {
242
                    $_GET[$key] = stripslashes($_GET[$key]);
243
                } else {
244
                    unset($_GET[$key]);
245
                }
246
            }
247
        }
248
    }
249
}
250
251
if (empty($_SERVER['PATH_INFO']) && empty($_SERVER['QUERY_STRING'])) {
252
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
253
    $phpThumb->ErrorImage('ERROR: no parameters specified');
254
}
255
256
if (!empty($_GET['src']) && isset($_GET['md5s']) && empty($_GET['md5s'])) {
257
    $md5s = '';
258
    if (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
259
        if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
260
            if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
261
                $md5s = md5($rawImageData);
262
            }
263
        } else {
264
            $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "' . $protocol_matches[1] . '" is not');
265
        }
266
    } else {
267
        $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($_GET['src']);
268
        if (is_readable($SourceFilename)) {
0 ignored issues
show
It seems like $SourceFilename 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 ignore-type  annotation

268
        if (is_readable(/** @scrutinizer ignore-type */ $SourceFilename)) {
Loading history...
269
            $md5s = phpthumb_functions::md5_file_safe($SourceFilename);
270
        } else {
271
            $phpThumb->ErrorImage('ERROR: "' . $SourceFilename . '" cannot be read');
272
        }
273
    }
274
    if (!empty($_SERVER['HTTP_REFERER'])) {
275
        $phpThumb->ErrorImage('&md5s=' . $md5s);
0 ignored issues
show
Are you sure $md5s 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 ignore-type  annotation

275
        $phpThumb->ErrorImage('&md5s=' . /** @scrutinizer ignore-type */ $md5s);
Loading history...
276
    } else {
277
        die('&md5s=' . $md5s);
278
    }
279
}
280
281
if (!empty($_GET['src']) && empty($phpThumb->config_allow_local_http_src) && preg_match('#^http://' . @$_SERVER['HTTP_HOST'] . '(.+)#i', $_GET['src'], $matches)) {
282
    $phpThumb->ErrorImage('It is MUCH better to specify the "src" parameter as "' . $matches[1] . '" instead of "' . $matches[0] . '".' . "\n\n" . 'If you really must do it this way, enable "allow_local_http_src" in phpThumb.config.php');
283
}
284
285
////////////////////////////////////////////////////////////////
286
// Debug output, to try and help me diagnose problems
287
$phpThumb->DebugTimingMessage('phpThumbDebug[1]', __FILE__, __LINE__);
288
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '1')) {
289
    $phpThumb->phpThumbDebug();
290
}
291
////////////////////////////////////////////////////////////////
292
293
$parsed_url_referer = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
294
if ($phpThumb->config_nooffsitelink_require_refer && !in_array(@$parsed_url_referer['host'], $phpThumb->config_nohotlink_valid_domains)) {
295
    $phpThumb->ErrorImage('config_nooffsitelink_require_refer enabled and ' . (@$parsed_url_referer['host'] ? '"' . $parsed_url_referer['host'] . '" is not an allowed referer' : 'no HTTP_REFERER exists'));
296
}
297
$parsed_url_src = phpthumb_functions::ParseURLbetter(@$_GET['src']);
298
if ($phpThumb->config_nohotlink_enabled && $phpThumb->config_nohotlink_erase_image && preg_match('#^(f|ht)tps?://#i', @$_GET['src']) && !in_array(@$parsed_url_src['host'], $phpThumb->config_nohotlink_valid_domains)) {
299
    $phpThumb->ErrorImage($phpThumb->config_nohotlink_text_message);
300
}
301
302
if ($phpThumb->config_mysql_query) {
303
    if ($phpThumb->config_mysql_extension == 'mysqli') {
304
        $found_missing_function = false;
305
        foreach (['mysqli_connect'] as $required_mysqli_function) {
306
            if (!function_exists($required_mysqli_function)) {
307
                $found_missing_function = $required_mysqli_function;
308
                break;
309
            }
310
        }
311
        if ($found_missing_function) {
312
            $phpThumb->ErrorImage('SQL function unavailable: ' . $found_missing_function);
313
        } else {
314
            $mysqli = new mysqli($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password, $phpThumb->config_mysql_database);
315
            if ($mysqli->connect_error) {
316
                $phpThumb->ErrorImage('MySQLi connect error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
317
            } else {
318
                if ($result = $mysqli->query($phpThumb->config_mysql_query)) {
319
                    if ($row = $result->fetch_array()) {
320
                        $result->free();
321
                        $mysqli->close();
322
                        $phpThumb->setSourceData($row[0]);
323
                        unset($row);
324
                    } else {
325
                        $result->free();
326
                        $mysqli->close();
327
                        $phpThumb->ErrorImage('no matching data in database.');
328
                    }
329
                } else {
330
                    $mysqli->close();
331
                    $phpThumb->ErrorImage('Error in MySQL query: "' . $mysqli->error . '"');
332
                }
333
            }
334
            unset($_GET['id']);
335
        }
336
    } elseif ($phpThumb->config_mysql_extension == 'mysql') {
337
        $found_missing_function = false;
338
        //foreach (array('mysql_connect', 'mysql_select_db', 'mysql_query', 'mysql_fetch_array', 'mysql_free_result', 'mysql_close', 'mysql_error') as $required_mysql_function) {
339
        foreach (['mysql_connect'] as $required_mysql_function) {
340
            if (!function_exists($required_mysql_function)) {
341
                $found_missing_function = $required_mysql_function;
342
                break;
343
            }
344
        }
345
        if ($found_missing_function) {
346
            $phpThumb->ErrorImage('SQL function unavailable: ' . $found_missing_function);
347
        } else {
348
            if ($cid = @mysql_connect($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password)) {
349
                if (@mysql_select_db($phpThumb->config_mysql_database, $cid)) {
350
                    if ($result = @mysql_query($phpThumb->config_mysql_query, $cid)) {
351
                        if ($row = @mysql_fetch_array($result)) {
0 ignored issues
show
It seems like $result can also be of type true; however, parameter $result of mysql_fetch_array() does only seem to accept resource, 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 ignore-type  annotation

351
                        if ($row = @mysql_fetch_array(/** @scrutinizer ignore-type */ $result)) {
Loading history...
352
                            mysql_free_result($result);
0 ignored issues
show
It seems like $result can also be of type true; however, parameter $result of mysql_free_result() does only seem to accept resource, 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 ignore-type  annotation

352
                            mysql_free_result(/** @scrutinizer ignore-type */ $result);
Loading history...
353
                            mysql_close($cid);
354
                            $phpThumb->setSourceData($row[0]);
355
                            unset($row);
356
                        } else {
357
                            mysql_free_result($result);
358
                            mysql_close($cid);
359
                            $phpThumb->ErrorImage('no matching data in database.');
360
                        }
361
                    } else {
362
                        mysql_close($cid);
363
                        $phpThumb->ErrorImage('Error in MySQL query: "' . mysql_error($cid) . '"');
364
                    }
365
                } else {
366
                    mysql_close($cid);
367
                    $phpThumb->ErrorImage('cannot select MySQL database: "' . mysql_error($cid) . '"');
368
                }
369
            } else {
370
                $phpThumb->ErrorImage('cannot connect to MySQL server');
371
            }
372
            unset($_GET['id']);
373
        }
374
    } else {
375
        $phpThumb->ErrorImage('config_mysql_extension not supported');
376
    }
377
}
378
379
////////////////////////////////////////////////////////////////
380
// Debug output, to try and help me diagnose problems
381
$phpThumb->DebugTimingMessage('phpThumbDebug[2]', __FILE__, __LINE__);
382
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '2')) {
383
    $phpThumb->phpThumbDebug();
384
}
385
////////////////////////////////////////////////////////////////
386
387
$PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = (bool)($phpThumb->config_cache_default_only_suffix && (strpos($phpThumb->config_cache_default_only_suffix, '*') !== false));
0 ignored issues
show
$phpThumb->config_cache_default_only_suffix of type true is incompatible with the type string expected by parameter $haystack of strpos(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

387
$PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = (bool)($phpThumb->config_cache_default_only_suffix && (strpos(/** @scrutinizer ignore-type */ $phpThumb->config_cache_default_only_suffix, '*') !== false));
Loading history...
388
389
// deprecated: 'err', 'file', 'goto',
390
$allowedGETparameters = ['src', 'new', 'w', 'h', 'wp', 'hp', 'wl', 'hl', 'ws', 'hs', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'zc', 'ica', 'bc', 'bg', 'bgt', 'fltr', 'xto', 'ra', 'ar', 'aoe', 'far', 'iar', 'maxb', 'down', 'phpThumbDebug', 'hash', 'md5s', 'sfn', 'dpi', 'sia', 'nocache'];
391
foreach ($_GET as $key => $value) {
392
    if (!empty($PHPTHUMB_DEFAULTS_DISABLEGETPARAMS) && ($key != 'src')) {
393
        // disabled, do not set parameter
394
        $phpThumb->DebugMessage('ignoring $_GET[' . $key . '] because of $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS', __FILE__, __LINE__);
395
    } elseif (in_array($key, $allowedGETparameters)) {
396
        $phpThumb->DebugMessage('setParameter(' . $key . ', ' . $phpThumb->phpThumbDebugVarDump($value) . ')', __FILE__, __LINE__);
397
        $phpThumb->setParameter($key, $value);
398
    } else {
399
        $phpThumb->ErrorImage('Forbidden parameter: ' . $key);
400
    }
401
}
402
403
if (!empty($PHPTHUMB_DEFAULTS) && is_array($PHPTHUMB_DEFAULTS)) {
404
    $phpThumb->DebugMessage('setting $PHPTHUMB_DEFAULTS[' . implode(';', array_keys($PHPTHUMB_DEFAULTS)) . ']', __FILE__, __LINE__);
405
    foreach ($PHPTHUMB_DEFAULTS as $key => $value) {
406
        if (!$PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE || !isset($_GET[$key])) { // set parameter to default value if config is set to allow _GET to override default, OR if no value is passed via _GET for this parameter
407
            //$_GET[$key] = $value;
408
            //$phpThumb->DebugMessage('PHPTHUMB_DEFAULTS assigning ('.(is_array($value) ? print_r($value, true) : $value).') to $_GET['.$key.']', __FILE__, __LINE__);
409
            $phpThumb->setParameter($key, $value);
410
            $phpThumb->DebugMessage('setParameter(' . $key . ', ' . $phpThumb->phpThumbDebugVarDump($value) . ') from $PHPTHUMB_DEFAULTS', __FILE__, __LINE__);
411
        }
412
    }
413
}
414
415
////////////////////////////////////////////////////////////////
416
// Debug output, to try and help me diagnose problems
417
$phpThumb->DebugTimingMessage('phpThumbDebug[3]', __FILE__, __LINE__);
418
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '3')) {
419
    $phpThumb->phpThumbDebug();
420
}
421
////////////////////////////////////////////////////////////////
422
423
//if (!@$_GET['phpThumbDebug'] && !is_file($phpThumb->sourceFilename) && !phpthumb_functions::gd_version()) {
424
//	if (!headers_sent()) {
425
//		// base64-encoded error image in GIF format
426
//		$ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7';
427
//		header('Content-Type: image/gif');
428
//		echo base64_decode($ERROR_NOGD);
429
//	} else {
430
//		echo '*** ERROR: No PHP-GD support available ***';
431
//	}
432
//	exit;
433
//}
434
435
// check to see if file can be output from source with no processing or caching
436
$CanPassThroughDirectly = true;
437
if ($phpThumb->rawImageData) {
438
    // data from SQL, should be fine
439
} elseif (preg_match('#^https?\\://[^\\?&]+\\.(jpe?g|gif|png|webp)$#i', $phpThumb->src)) {
440
    // assume is ok to passthru if no other parameters specified
441
} elseif (preg_match('#^(f|ht)tps?\\://#i', $phpThumb->src)) {
442
    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because preg_match("#^(f|ht)tps?://#i", ' . $phpThumb->src . ')', __FILE__, __LINE__);
443
    $CanPassThroughDirectly = false;
444
} elseif (!@is_readable($phpThumb->sourceFilename)) {
445
    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_readable(' . $phpThumb->sourceFilename . ')', __FILE__, __LINE__);
446
    $CanPassThroughDirectly = false;
447
} elseif (!@is_file($phpThumb->sourceFilename)) {
448
    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_file(' . $phpThumb->sourceFilename . ')', __FILE__, __LINE__);
449
    $CanPassThroughDirectly = false;
450
}
451
foreach ($_GET as $key => $value) {
452
    switch ($key) {
453
        case 'src':
454
            // allowed
455
            break;
456
457
        case 'w':
458
        case 'h':
459
            // might be OK if exactly matches original
460
            if (preg_match('#^https?\\://[^\\?&]+\\.(jpe?g|gif|png|webp)$#i', $phpThumb->src)) {
461
                // assume it is not ok for direct-passthru of remote image
462
                $CanPassThroughDirectly = false;
463
            }
464
            break;
465
466
        case 'phpThumbDebug':
467
            // handled in direct-passthru code
468
            break;
469
470
        default:
471
            // all other parameters will cause some processing,
472
            // therefore cannot pass through original image unmodified
473
            $CanPassThroughDirectly = false;
474
            $UnAllowedGET[]         = $key;
475
            break;
476
    }
477
}
478
if (!empty($UnAllowedGET)) {
479
    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because $_GET[' . implode(';', array_unique($UnAllowedGET)) . '] are set', __FILE__, __LINE__);
480
}
481
482
////////////////////////////////////////////////////////////////
483
// Debug output, to try and help me diagnose problems
484
$phpThumb->DebugTimingMessage('phpThumbDebug[4]', __FILE__, __LINE__);
485
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '4')) {
486
    $phpThumb->phpThumbDebug();
487
}
488
////////////////////////////////////////////////////////////////
489
490
$phpThumb->DebugMessage('$CanPassThroughDirectly="' . (int)$CanPassThroughDirectly . '" && $phpThumb->src="' . $phpThumb->src . '"', __FILE__, __LINE__);
491
while ($CanPassThroughDirectly && $phpThumb->src) {
492
    // no parameters set, passthru
493
494
    if (preg_match('#^https?\\://[^\\?&]+\.(jpe?g|gif|png|webp)$#i', $phpThumb->src)) {
495
        $phpThumb->DebugMessage('Passing HTTP source through directly as Location: redirect (' . $phpThumb->src . ')', __FILE__, __LINE__);
496
        header('Location: ' . $phpThumb->src);
497
        exit;
498
    }
499
500
    $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($phpThumb->src);
501
502
    // security and size checks
503
    if ($phpThumb->getimagesizeinfo = @getimagesize($SourceFilename)) {
0 ignored issues
show
It seems like $SourceFilename can also be of type false and null; however, parameter $filename of getimagesize() 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 ignore-type  annotation

503
    if ($phpThumb->getimagesizeinfo = @getimagesize(/** @scrutinizer ignore-type */ $SourceFilename)) {
Loading history...
504
        $phpThumb->DebugMessage('Direct passthru getimagesize() returned [w=' . $phpThumb->getimagesizeinfo[0] . ';h=' . $phpThumb->getimagesizeinfo[1] . ';t=' . $phpThumb->getimagesizeinfo[2] . ']', __FILE__, __LINE__);
505
506
        if (!@$_GET['w'] && !@$_GET['wp'] && !@$_GET['wl'] && !@$_GET['ws'] && !@$_GET['h'] && !@$_GET['hp'] && !@$_GET['hl'] && !@$_GET['hs']) {
507
            // no resizing needed
508
            $phpThumb->DebugMessage('Passing "' . $SourceFilename . '" through directly, no resizing required ("' . $phpThumb->getimagesizeinfo[0] . '"x"' . $phpThumb->getimagesizeinfo[1] . '")', __FILE__, __LINE__);
509
        } elseif (($phpThumb->getimagesizeinfo[0] <= @$_GET['w']) && ($phpThumb->getimagesizeinfo[1] <= @$_GET['h']) && ((@$_GET['w'] == $phpThumb->getimagesizeinfo[0]) || (@$_GET['h'] == $phpThumb->getimagesizeinfo[1]))) {
510
            // image fits into 'w'x'h' box, and at least one dimension matches exactly, therefore no resizing needed
511
            $phpThumb->DebugMessage('Passing "' . $SourceFilename . '" through directly, no resizing required ("' . $phpThumb->getimagesizeinfo[0] . '"x"' . $phpThumb->getimagesizeinfo[1] . '" fits inside "' . @$_GET['w'] . '"x"' . @$_GET['h'] . '")', __FILE__, __LINE__);
512
        } else {
513
            $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because resizing required (from "' . $phpThumb->getimagesizeinfo[0] . '"x"' . $phpThumb->getimagesizeinfo[1] . '" to "' . @$_GET['w'] . '"x"' . @$_GET['h'] . '")', __FILE__, __LINE__);
514
            break;
515
        }
516
        switch ($phpThumb->getimagesizeinfo[2]) {
517
            case  1: // GIF
518
            case  2: // JPG
519
            case  3: // PNG
520
            case 18: // WEBP
521
                // great, let it through
522
                break;
523
            default:
524
                // browser probably can't handle format, remangle it to JPEG/PNG/GIF
525
                $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because $phpThumb->getimagesizeinfo[2] = "' . $phpThumb->getimagesizeinfo[2] . '"', __FILE__, __LINE__);
526
                break 2;
527
        }
528
529
        $ImageCreateFunctions   = [1 => 'imagecreatefromgif', 2 => 'imagecreatefromjpeg', 3 => 'imagecreatefrompng', 18 => 'imagecreatefromwebp'];
530
        $theImageCreateFunction = @$ImageCreateFunctions[$phpThumb->getimagesizeinfo[2]];
531
        $dummyImage             = false;
532
        if ($phpThumb->config_disable_onlycreateable_passthru || (function_exists($theImageCreateFunction) && ($dummyImage = @$theImageCreateFunction($SourceFilename)))) {
533
            // great
534
            if (@is_resource($dummyImage) || (@is_object($dummyImage) && $dummyImage instanceof \GdImage)) {
535
                unset($dummyImage);
536
            }
537
538
            if (headers_sent()) {
539
                $phpThumb->ErrorImage('Headers already sent (' . basename(__FILE__) . ' line ' . __LINE__ . ')');
540
                exit;
541
            }
542
            if (!empty($_GET['phpThumbDebug'])) {
543
                $phpThumb->DebugTimingMessage('skipped direct $SourceFilename passthru', __FILE__, __LINE__);
544
                $phpThumb->DebugMessage('Would have passed "' . $SourceFilename . '" through directly, but skipping due to phpThumbDebug', __FILE__, __LINE__);
545
                break;
546
            }
547
548
            SendSaveAsFileHeaderIfNeeded($phpThumb->getimagesizeinfo);
549
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime($SourceFilename)) . ' GMT');
0 ignored issues
show
It seems like @filemtime($SourceFilename) can also be of type false; however, parameter $timestamp of gmdate() does only seem to accept integer|null, 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 ignore-type  annotation

549
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', /** @scrutinizer ignore-type */ @filemtime($SourceFilename)) . ' GMT');
Loading history...
It seems like $SourceFilename can also be of type false and null; however, parameter $filename of filemtime() 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 ignore-type  annotation

549
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime(/** @scrutinizer ignore-type */ $SourceFilename)) . ' GMT');
Loading history...
550
            if ($contentType = phpthumb_functions::ImageTypeToMIMEtype(@$phpThumb->getimagesizeinfo[2])) {
551
                header('Content-Type: ' . $contentType);
552
            }
553
            echo file_get_contents($SourceFilename);
0 ignored issues
show
It seems like $SourceFilename 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 ignore-type  annotation

553
            echo file_get_contents(/** @scrutinizer ignore-type */ $SourceFilename);
Loading history...
554
            exit;
555
        } else {
556
            $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because ($phpThumb->config_disable_onlycreateable_passthru = "' . $phpThumb->config_disable_onlycreateable_passthru . '") and ' . $theImageCreateFunction . '() failed', __FILE__, __LINE__);
0 ignored issues
show
Are you sure $phpThumb->config_disable_onlycreateable_passthru of type false 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 ignore-type  annotation

556
            $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because ($phpThumb->config_disable_onlycreateable_passthru = "' . /** @scrutinizer ignore-type */ $phpThumb->config_disable_onlycreateable_passthru . '") and ' . $theImageCreateFunction . '() failed', __FILE__, __LINE__);
Loading history...
557
            break;
558
        }
559
    } else {
560
        $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because getimagesize() failed', __FILE__, __LINE__);
561
        break;
562
    }
563
    break;
564
}
565
566
////////////////////////////////////////////////////////////////
567
// Debug output, to try and help me diagnose problems
568
$phpThumb->DebugTimingMessage('phpThumbDebug[5]', __FILE__, __LINE__);
569
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '5')) {
570
    $phpThumb->phpThumbDebug();
571
}
572
////////////////////////////////////////////////////////////////
573
574
// check to see if file already exists in cache, and output it with no processing if it does
575
$phpThumb->SetCacheFilename();
576
if (@is_readable($phpThumb->cache_filename)) {
577
    RedirectToCachedFile();
578
} else {
579
    $phpThumb->DebugMessage('Cached file "' . $phpThumb->cache_filename . '" does not exist, processing as normal', __FILE__, __LINE__);
580
}
581
582
////////////////////////////////////////////////////////////////
583
// Debug output, to try and help me diagnose problems
584
$phpThumb->DebugTimingMessage('phpThumbDebug[6]', __FILE__, __LINE__);
585
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '6')) {
586
    $phpThumb->phpThumbDebug();
587
}
588
////////////////////////////////////////////////////////////////
589
590
if ($phpThumb->rawImageData) {
591
    // great
592
593
} elseif (!empty($_GET['new'])) {
594
    // generate a blank image resource of the specified size/background color/opacity
595
    if (($phpThumb->w <= 0) || ($phpThumb->h <= 0)) {
596
        $phpThumb->ErrorImage('"w" and "h" parameters required for "new"');
597
    }
598
    @list($bghexcolor, $opacity) = explode('|', $_GET['new']);
599
    if (!phpthumb_functions::IsHexColor($bghexcolor)) {
600
        $phpThumb->ErrorImage('BGcolor parameter for "new" is not valid');
601
    }
602
    $opacity = ('' !== $opacity ? $opacity : 100);
603
    if ($phpThumb->gdimg_source = phpthumb_functions::ImageCreateFunction($phpThumb->w, $phpThumb->h)) {
604
        $alpha = (100 - min(100, max(0, $opacity))) * 1.27;
605
        if ($alpha) {
606
            $phpThumb->setParameter('is_alpha', true);
607
            imagealphablending($phpThumb->gdimg_source, false);
608
            imagesavealpha($phpThumb->gdimg_source, true);
609
        }
610
        $new_background_color = phpthumb_functions::ImageHexColorAllocate($phpThumb->gdimg_source, $bghexcolor, false, $alpha);
611
        imagefilledrectangle($phpThumb->gdimg_source, 0, 0, $phpThumb->w, $phpThumb->h, $new_background_color);
612
    } else {
613
        $phpThumb->ErrorImage('failed to create "new" image (' . $phpThumb->w . 'x' . $phpThumb->h . ')');
614
    }
615
} elseif (!$phpThumb->src) {
616
    $phpThumb->ErrorImage('Usage: ' . $_SERVER['PHP_SELF'] . '?src=/path/and/filename.jpg' . "\n" . 'read Usage comments for details');
617
} elseif (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
618
    if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
619
        $phpThumb->DebugMessage('$phpThumb->src (' . $phpThumb->src . ') is remote image, attempting to download', __FILE__, __LINE__);
620
        if ($phpThumb->config_http_user_agent) {
621
            $phpThumb->DebugMessage('Setting "user_agent" to "' . $phpThumb->config_http_user_agent . '"', __FILE__, __LINE__);
622
            ini_set('user_agent', $phpThumb->config_http_user_agent);
623
        }
624
        $cleanedupurl = phpthumb_functions::CleanUpURLencoding($phpThumb->src);
625
        $phpThumb->DebugMessage('CleanUpURLencoding(' . $phpThumb->src . ') returned "' . $cleanedupurl . '"', __FILE__, __LINE__);
626
        $phpThumb->src = $cleanedupurl;
627
        unset($cleanedupurl);
628
        if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
629
            $phpThumb->DebugMessage('SafeURLread(' . $phpThumb->src . ') succeeded' . ($error ? ' with messages: "' . $error . '"' : ''), __FILE__, __LINE__);
630
            $phpThumb->DebugMessage('Setting source data from URL "' . $phpThumb->src . '"', __FILE__, __LINE__);
631
            $phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
632
        } else {
633
            $phpThumb->ErrorImage($error);
634
        }
635
    } else {
636
        $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "' . $protocol_matches[1] . '" is not');
637
    }
638
}
639
640
////////////////////////////////////////////////////////////////
641
// Debug output, to try and help me diagnose problems
642
$phpThumb->DebugTimingMessage('phpThumbDebug[7]', __FILE__, __LINE__);
643
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '7')) {
644
    $phpThumb->phpThumbDebug();
645
}
646
////////////////////////////////////////////////////////////////
647
648
$phpThumb->GenerateThumbnail();
649
650
////////////////////////////////////////////////////////////////
651
// Debug output, to try and help me diagnose problems
652
$phpThumb->DebugTimingMessage('phpThumbDebug[8]', __FILE__, __LINE__);
653
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '8')) {
654
    $phpThumb->phpThumbDebug();
655
}
656
////////////////////////////////////////////////////////////////
657
658
if (!empty($phpThumb->config_high_security_enabled) && !empty($_GET['nocache'])) {
659
    // cache disabled, don't write cachefile
660
661
} else {
662
    phpthumb_functions::EnsureDirectoryExists(dirname($phpThumb->cache_filename));
663
    if (is_writable(dirname($phpThumb->cache_filename)) || (file_exists($phpThumb->cache_filename) && is_writable($phpThumb->cache_filename))) {
664
        $phpThumb->CleanUpCacheDirectory();
665
        if ($phpThumb->RenderToFile($phpThumb->cache_filename) && is_readable($phpThumb->cache_filename)) {
666
            chmod($phpThumb->cache_filename, 0644);
667
            RedirectToCachedFile();
668
        } else {
669
            $phpThumb->DebugMessage('Failed: RenderToFile(' . $phpThumb->cache_filename . ')', __FILE__, __LINE__);
670
        }
671
    } else {
672
        $phpThumb->DebugMessage('Cannot write to $phpThumb->cache_filename (' . $phpThumb->cache_filename . ') because that directory (' . dirname($phpThumb->cache_filename) . ') is not writable', __FILE__, __LINE__);
673
    }
674
}
675
676
////////////////////////////////////////////////////////////////
677
// Debug output, to try and help me diagnose problems
678
$phpThumb->DebugTimingMessage('phpThumbDebug[9]', __FILE__, __LINE__);
679
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '9')) {
680
    $phpThumb->phpThumbDebug();
681
}
682
////////////////////////////////////////////////////////////////
683
684
if (!$phpThumb->OutputThumbnail()) {
685
    $phpThumb->ErrorImage('Error in OutputThumbnail():' . "\n" . $phpThumb->debugmessages[count($phpThumb->debugmessages) - 1]);
686
}
687
688
////////////////////////////////////////////////////////////////
689
// Debug output, to try and help me diagnose problems
690
$phpThumb->DebugTimingMessage('phpThumbDebug[10]', __FILE__, __LINE__);
691
if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '10')) {
692
    $phpThumb->phpThumbDebug();
693
}
694
////////////////////////////////////////////////////////////////
695