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.

0old/phpthumb/phpThumb.php (14 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
ini_set('magic_quotes_runtime', '0');
16
if (ini_get('magic_quotes_runtime')) {
17
    exit('"magic_quotes_runtime" is set in php.ini, cannot run phpThumb with this enabled');
18
}
19
// Set a default timezone if web server has not done already in php.ini
20
if (!ini_get('date.timezone') && function_exists('date_default_timezone_set')) { // PHP >= 5.1.0
21
    date_default_timezone_set('UTC');
22
}
23
$starttime = array_sum(explode(' ', microtime())); // could be called as microtime(true) for PHP 5.0.0+
24
25
// this script relies on the superglobal arrays, fake it here for old PHP versions
26
if (PHP_VERSION < '4.1.0') {
27
    $_SERVER = $HTTP_SERVER_VARS;
28
    $_GET    = $_GET;
29
}
30
31
/**
32
 * @return bool
33
 */
34
function SendSaveAsFileHeaderIfNeeded()
35
{
36
    if (headers_sent()) {
37
        return false;
38
    }
39
    global $phpThumb;
40
    $downloadfilename = phpthumb_functions::SanitizeFilename(!empty($_GET['sia']) ? $_GET['sia'] : (!empty($_GET['down']) ? $_GET['down'] : 'phpThumb_generated_thumbnail.' . (!empty($_GET['f']) ? $_GET['f'] : 'jpg')));
41
    if (!empty($downloadfilename)) {
42
        $phpThumb->DebugMessage('SendSaveAsFileHeaderIfNeeded() sending header: Content-Disposition: ' . (!empty($_GET['down']) ? 'attachment' : 'inline') . '; filename="' . $downloadfilename . '"', __FILE__, __LINE__);
43
        header('Content-Disposition: ' . (!empty($_GET['down']) ? 'attachment' : 'inline') . '; filename="' . $downloadfilename . '"');
44
    }
45
46
    return true;
47
}
48
49
/**
50
 * @return bool
51
 */
52
function RedirectToCachedFile()
53
{
54
    global $phpThumb;
55
56
    $nice_cachefile = str_replace(DIRECTORY_SEPARATOR, '/', $phpThumb->cache_filename);
57
    $nice_docroot   = str_replace(DIRECTORY_SEPARATOR, '/', rtrim($phpThumb->config_document_root, '/\\'));
58
59
    $parsed_url = phpthumb_functions::ParseURLbetter(@\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER'));
60
61
    $nModified = filemtime($phpThumb->cache_filename);
62
63
    if ($phpThumb->config_nooffsitelink_enabled && !empty(\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER')) && !in_array(@$parsed_url['host'], $phpThumb->config_nooffsitelink_valid_domains, true)) {
64
        $phpThumb->DebugMessage(
65
            'Would have used cached (image/'
66
            . $phpThumb->thumbnailFormat
67
            . ') file "'
68
            . $phpThumb->cache_filename
69
            . '" (Last-Modified: '
70
            . gmdate('D, d M Y H:i:s', $nModified)
71
            . ' GMT), but skipping because $_SERVER[HTTP_REFERER] ('
72
            . @\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER')
73
            . ') is not in $phpThumb->config_nooffsitelink_valid_domains ('
74
            . implode(';', $phpThumb->config_nooffsitelink_valid_domains)
75
            . ')',
76
            __FILE__,
77
            __LINE__
78
        );
79
    } elseif ($phpThumb->phpThumbDebug) {
80
        $phpThumb->DebugTimingMessage('skipped using cached image', __FILE__, __LINE__);
81
        $phpThumb->DebugMessage('Would have used cached file, but skipping due to phpThumbDebug', __FILE__, __LINE__);
82
        $phpThumb->DebugMessage('* Would have sent headers (1): Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT', __FILE__, __LINE__);
83
        if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
84
            $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

84
            $phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: ' . /** @scrutinizer ignore-type */ phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
Loading history...
85
        }
86
        if (preg_match('#^' . preg_quote($nice_docroot) . '(.*)$#', $nice_cachefile, $matches)) {
87
            $phpThumb->DebugMessage('* Would have sent headers (3): Location: ' . \dirname($matches[1]) . '/' . urlencode(basename($matches[1])), __FILE__, __LINE__);
88
        } else {
89
            $phpThumb->DebugMessage('* Would have sent data: readfile(' . $phpThumb->cache_filename . ')', __FILE__, __LINE__);
90
        }
91
    } else {
92
        if (headers_sent()) {
93
            $phpThumb->ErrorImage('Headers already sent (' . basename(__FILE__) . ' line ' . __LINE__ . ')');
94
            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...
95
        }
96
        SendSaveAsFileHeaderIfNeeded();
97
98
        header('Cache-Control: private');
99
        header('Pragma: private');
100
        header('Cache-Control: max-age=' . $phpThumb->getParameter('config_cache_maxage'));
101
        header('Expires: ' . date(DATE_RFC1123, time() + $phpThumb->getParameter('config_cache_maxage')));
102
        if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
103
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT');
104
            header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
105
            exit;
106
        }
107
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $nModified) . ' GMT');
108
        header('ETag: "' . md5_file($phpThumb->cache_filename) . '"');
109
        if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
110
            header('Content-Type: ' . phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]));
111
        } elseif (preg_match('#\\.ico$#i', $phpThumb->cache_filename)) {
112
            header('Content-Type: image/x-icon');
113
        }
114
        header('Content-Length: ' . filesize($phpThumb->cache_filename));
115
        if (empty($phpThumb->config_cache_force_passthru) && preg_match('#^' . preg_quote($nice_docroot) . '(.*)$#', $nice_cachefile, $matches)) {
116
            header('Location: ' . \dirname($matches[1]) . '/' . urlencode(basename($matches[1])));
117
        } else {
118
            @readfile($phpThumb->cache_filename);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for readfile(). 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 ignore-unhandled  annotation

118
            /** @scrutinizer ignore-unhandled */ @readfile($phpThumb->cache_filename);

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.');
}
Loading history...
119
        }
120
        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...
121
    }
122
123
    return true;
124
}
125
126
// instantiate a new phpThumb() object
127
ob_start();
128
if (!require_once __DIR__ . '/phpthumb.class.php') {
129
    ob_end_flush();
130
    exit('failed to include_once("' . realpath(__DIR__ . '/phpthumb.class.php') . '")');
131
}
132
ob_end_clean();
133
$phpThumb = new phpThumb();
134
$phpThumb->DebugTimingMessage('phpThumb.php start', __FILE__, __LINE__, $starttime);
135
$phpThumb->setParameter('config_error_die_on_error', true);
136
137
if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
138
    set_time_limit(60);  // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
139
}
140
141
// phpThumbDebug[0] used to be here, but may reveal too much
142
// info when high_security_mode should be enabled (not set yet)
143
144
if (file_exists(__DIR__ . '/phpThumb.config.php')) {
145
    ob_start();
146
    if (require_once __DIR__ . '/phpThumb.config.php') {
147
        // great
148
    } else {
149
        ob_end_flush();
150
        $phpThumb->config_disable_debug = false; // otherwise error message won't print
151
        $phpThumb->ErrorImage('failed to include_once(' . __DIR__ . '/phpThumb.config.php) - realpath="' . realpath(__DIR__ . '/phpThumb.config.php') . '"');
152
    }
153
    ob_end_clean();
154
} elseif (file_exists(__DIR__ . '/phpThumb.config.php.default')) {
155
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
156
    $phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
157
} else {
158
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
159
    $phpThumb->ErrorImage('failed to include_once(' . __DIR__ . '/phpThumb.config.php) - realpath="' . realpath(__DIR__ . '/phpThumb.config.php') . '"');
160
}
161
162
if (!empty($PHPTHUMB_CONFIG)) {
163
    foreach ($PHPTHUMB_CONFIG as $key => $value) {
164
        $keyname = 'config_' . $key;
165
        $phpThumb->setParameter($keyname, $value);
166
        if (!preg_match('#(password|mysql)#i', $key)) {
167
            $phpThumb->DebugMessage('setParameter(' . $keyname . ', ' . $phpThumb->phpThumbDebugVarDump($value) . ')', __FILE__, __LINE__);
168
        }
169
    }
170
    if (!$phpThumb->config_disable_debug) {
171
        // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
172
        $_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, \Xmf\Request::getInt('phpThumbDebug', 0, 'GET')) : 9);
173
        $phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
174
    }
175
} else {
176
    $phpThumb->DebugMessage('$PHPTHUMB_CONFIG is empty', __FILE__, __LINE__);
177
}
178
179
if (empty($phpThumb->config_disable_pathinfo_parsing) && (empty($_GET) || isset($_GET['phpThumbDebug']))
180
    && !empty($_SERVER['PATH_INFO'])) {
181
    $_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);
182
183
    $args = explode(';', mb_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('#^([0-9]*)x?([0-9]*)$#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 ('[]' === mb_substr($key, -2)) {
201
            $array_key_name          = mb_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']) && ('0' == $_GET['phpThumbDebug'])) {
229
    $phpThumb->phpThumbDebug();
230
}
231
////////////////////////////////////////////////////////////////
232
233
// returned the fixed string if the evil "magic_quotes_gpc" setting is on
234
if (get_magic_quotes_gpc()) {
235
    // deprecated: 'err', 'file', 'goto',
236
    $RequestVarsToStripSlashes = ['src', 'wmf', 'down'];
237
    foreach ($RequestVarsToStripSlashes as $key) {
238
        if (isset($_GET[$key])) {
239
            if (is_string($_GET[$key])) {
240
                $_GET[$key] = stripslashes($_GET[$key]);
241
            } else {
242
                unset($_GET[$key]);
243
            }
244
        }
245
    }
246
}
247
248
if (empty($_SERVER['PATH_INFO']) && empty($_SERVER['QUERY_STRING'])) {
249
    $phpThumb->config_disable_debug = false; // otherwise error message won't print
250
    $phpThumb->ErrorImage('ERROR: no parameters specified');
251
}
252
253
if (!empty($_GET['src']) && isset($_GET['md5s']) && empty($_GET['md5s'])) {
254
    $md5s = '';
255
    if (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
256
        if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
257
            if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
258
                $md5s = md5($rawImageData);
259
            }
260
        } else {
261
            $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "' . $protocol_matches[1] . '" is not');
262
        }
263
    } else {
264
        $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($_GET['src']);
265
        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

265
        if (is_readable(/** @scrutinizer ignore-type */ $SourceFilename)) {
Loading history...
266
            $md5s = phpthumb_functions::md5_file_safe($SourceFilename);
267
        } else {
268
            $phpThumb->ErrorImage('ERROR: "' . $SourceFilename . '" cannot be read');
269
        }
270
    }
271
    if (\Xmf\Request::hasVar('HTTP_REFERER', 'SERVER')) {
272
        $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

272
        $phpThumb->ErrorImage('&md5s=' . /** @scrutinizer ignore-type */ $md5s);
Loading history...
273
    } else {
274
        exit('&md5s=' . $md5s);
275
    }
276
}
277
278
if (!empty($_GET['src']) && empty($phpThumb->config_allow_local_http_src)
279
    && preg_match('#^http://' . @$_SERVER['HTTP_HOST'] . '(.+)#i', $_GET['src'], $matches)) {
280
    $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');
281
}
282
283
////////////////////////////////////////////////////////////////
284
// Debug output, to try and help me diagnose problems
285
$phpThumb->DebugTimingMessage('phpThumbDebug[1]', __FILE__, __LINE__);
286
if (isset($_GET['phpThumbDebug']) && ('1' == $_GET['phpThumbDebug'])) {
287
    $phpThumb->phpThumbDebug();
288
}
289
////////////////////////////////////////////////////////////////
290
291
$parsed_url_referer = phpthumb_functions::ParseURLbetter(@\Xmf\Request::getString('HTTP_REFERER', '', 'SERVER'));
292
if ($phpThumb->config_nooffsitelink_require_refer
293
    && !in_array(@$parsed_url_referer['host'], $phpThumb->config_nohotlink_valid_domains, true)) {
294
    $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'));
295
}
296
$parsed_url_src = phpthumb_functions::ParseURLbetter(@$_GET['src']);
297
if ($phpThumb->config_nohotlink_enabled && $phpThumb->config_nohotlink_erase_image
298
    && preg_match('#^(f|ht)tps?://#i', @$_GET['src'])
299
    && !in_array(@$parsed_url_src['host'], $phpThumb->config_nohotlink_valid_domains, true)) {
300
    $phpThumb->ErrorImage($phpThumb->config_nohotlink_text_message);
301
}
302
303
if ($phpThumb->config_mysql_query) {
304
    if ('mysqli' === $phpThumb->config_mysql_extension) {
305
        $found_missing_function = false;
306
        foreach (['mysqli_connect'] as $required_mysqli_function) {
307
            if (!function_exists($required_mysqli_function)) {
308
                $found_missing_function = $required_mysqli_function;
309
                break;
310
            }
311
        }
312
        if ($found_missing_function) {
313
            $phpThumb->ErrorImage('SQL function unavailable: ' . $found_missing_function);
314
        } else {
315
            $mysqli = new mysqli($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password, $phpThumb->config_mysql_database);
316
            if ($mysqli->connect_error) {
317
                $phpThumb->ErrorImage('MySQLi connect error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
318
            } else {
319
                if ($result = $mysqli->query($phpThumb->config_mysql_query)) {
320
                    if ($row = $result->fetch_array()) {
321
                        $result->free();
322
                        $mysqli->close();
323
                        $phpThumb->setSourceData($row[0]);
324
                        unset($row);
325
                    } else {
326
                        $result->free();
327
                        $mysqli->close();
328
                        $phpThumb->ErrorImage('no matching data in database.');
329
                    }
330
                } else {
331
                    $mysqli->close();
332
                    $phpThumb->ErrorImage('Error in MySQL query: "' . $mysqli->error . '"');
333
                }
334
            }
335
            unset($_GET['id']);
336
        }
337
    } elseif ('mysql' === $phpThumb->config_mysql_extension) {
338
        $found_missing_function = false;
339
        //foreach (array('mysql_connect', 'mysql_select_db', 'mysql_query', 'mysql_fetch_array', 'mysql_free_result', '$GLOBALS['xoopsDB']->close', 'mysql_error') as $required_mysql_function) {
340
        foreach (['mysql_connect'] as $required_mysql_function) {
341
            if (!function_exists($required_mysql_function)) {
342
                $found_missing_function = $required_mysql_function;
343
                break;
344
            }
345
        }
346
        if ($found_missing_function) {
347
            $phpThumb->ErrorImage('SQL function unavailable: ' . $found_missing_function);
348
        } else {
349
            if ($cid = @mysql_connect($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password)) {
350
                if (@mysqli_select_db($GLOBALS['xoopsDB']->conn, $phpThumb->config_mysql_database, $cid)) {
0 ignored issues
show
The call to mysqli_select_db() has too many arguments starting with $cid. ( Ignorable by Annotation )

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

350
                if (@/** @scrutinizer ignore-call */ mysqli_select_db($GLOBALS['xoopsDB']->conn, $phpThumb->config_mysql_database, $cid)) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
351
                    if ($result = @$GLOBALS['xoopsDB']->queryF($phpThumb->config_mysql_query, $cid)) {
352
                        if ($row = @$GLOBALS['xoopsDB']->fetchBoth($result)) {
353
                            $GLOBALS['xoopsDB']->freeRecordSet($result);
354
                            $GLOBALS['xoopsDB']->close($cid);
355
                            $phpThumb->setSourceData($row[0]);
356
                            unset($row);
357
                        } else {
358
                            $GLOBALS['xoopsDB']->freeRecordSet($result);
359
                            $GLOBALS['xoopsDB']->close($cid);
360
                            $phpThumb->ErrorImage('no matching data in database.');
361
                        }
362
                    } else {
363
                        $GLOBALS['xoopsDB']->close($cid);
364
                        $phpThumb->ErrorImage('Error in MySQL query: "' . $GLOBALS['xoopsDB']->error($cid) . '"');
365
                    }
366
                } else {
367
                    $GLOBALS['xoopsDB']->close($cid);
368
                    $phpThumb->ErrorImage('cannot select MySQL database: "' . $GLOBALS['xoopsDB']->error($cid) . '"');
369
                }
370
            } else {
371
                $phpThumb->ErrorImage('cannot connect to MySQL server');
372
            }
373
            unset($_GET['id']);
374
        }
375
    } else {
376
        $phpThumb->ErrorImage('config_mysql_extension not supported');
377
    }
378
}
379
380
////////////////////////////////////////////////////////////////
381
// Debug output, to try and help me diagnose problems
382
$phpThumb->DebugTimingMessage('phpThumbDebug[2]', __FILE__, __LINE__);
383
if (isset($_GET['phpThumbDebug']) && ('2' == $_GET['phpThumbDebug'])) {
384
    $phpThumb->phpThumbDebug();
385
}
386
////////////////////////////////////////////////////////////////
387
388
$PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = ($phpThumb->config_cache_default_only_suffix
389
                                       && (false !== mb_strpos($phpThumb->config_cache_default_only_suffix, '*')));
0 ignored issues
show
$phpThumb->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 ignore-type  annotation

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

540
    if ($phpThumb->getimagesizeinfo = @getimagesize(/** @scrutinizer ignore-type */ $SourceFilename)) {
Loading history...
541
        $phpThumb->DebugMessage('Direct passthru getimagesize() returned [w=' . $phpThumb->getimagesizeinfo[0] . ';h=' . $phpThumb->getimagesizeinfo[1] . ';t=' . $phpThumb->getimagesizeinfo[2] . ']', __FILE__, __LINE__);
542
543
        if (!@$_GET['w'] && !@$_GET['wp'] && !@$_GET['wl'] && !@$_GET['ws'] && !@$_GET['h'] && !@$_GET['hp']
544
            && !@$_GET['hl']
545
            && !@$_GET['hs']) {
546
            // no resizing needed
547
            $phpThumb->DebugMessage('Passing "' . $SourceFilename . '" through directly, no resizing required ("' . $phpThumb->getimagesizeinfo[0] . '"x"' . $phpThumb->getimagesizeinfo[1] . '")', __FILE__, __LINE__);
548
        } elseif (($phpThumb->getimagesizeinfo[0] <= @$_GET['w']) && ($phpThumb->getimagesizeinfo[1] <= @$_GET['h'])
549
                  && ((@$_GET['w'] == $phpThumb->getimagesizeinfo[0])
550
                      || (@$_GET['h'] == $phpThumb->getimagesizeinfo[1]))) {
551
            // image fits into 'w'x'h' box, and at least one dimension matches exactly, therefore no resizing needed
552
            $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__);
553
        } else {
554
            $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__);
555
            break;
556
        }
557
        switch ($phpThumb->getimagesizeinfo[2]) {
558
            case 1: // GIF
559
            case 2: // JPG
560
            case 3: // PNG
561
                // great, let it through
562
                break;
563
            default:
564
                // browser probably can't handle format, remangle it to JPEG/PNG/GIF
565
                $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because $phpThumb->getimagesizeinfo[2] = "' . $phpThumb->getimagesizeinfo[2] . '"', __FILE__, __LINE__);
566
                break 2;
567
        }
568
569
        $ImageCreateFunctions   = [
570
            1 => 'imagecreatefromgif',
571
            2 => 'imagecreatefromjpeg',
572
            3 => 'imagecreatefrompng',
573
        ];
574
        $theImageCreateFunction = @$ImageCreateFunctions[$phpThumb->getimagesizeinfo[2]];
575
        $dummyImage             = false;
576
        if ($phpThumb->config_disable_onlycreateable_passthru
577
            || (function_exists($theImageCreateFunction)
578
                && ($dummyImage = @$theImageCreateFunction($SourceFilename)))) {
579
            // great
580
            if (@is_resource($dummyImage)) {
581
                unset($dummyImage);
582
            }
583
584
            if (headers_sent()) {
585
                $phpThumb->ErrorImage('Headers already sent (' . basename(__FILE__) . ' line ' . __LINE__ . ')');
586
                exit;
587
            }
588
            if (\Xmf\Request::hasVar('phpThumbDebug', 'GET')) {
589
                $phpThumb->DebugTimingMessage('skipped direct $SourceFilename passthru', __FILE__, __LINE__);
590
                $phpThumb->DebugMessage('Would have passed "' . $SourceFilename . '" through directly, but skipping due to phpThumbDebug', __FILE__, __LINE__);
591
                break;
592
            }
593
594
            SendSaveAsFileHeaderIfNeeded();
595
            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

595
            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

595
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime(/** @scrutinizer ignore-type */ $SourceFilename)) . ' GMT');
Loading history...
596
            if ($contentType = phpthumb_functions::ImageTypeToMIMEtype(@$phpThumb->getimagesizeinfo[2])) {
597
                header('Content-Type: ' . $contentType);
598
            }
599
            @readfile($SourceFilename);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for readfile(). 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 ignore-unhandled  annotation

599
            /** @scrutinizer ignore-unhandled */ @readfile($SourceFilename);

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.');
}
Loading history...
It seems like $SourceFilename can also be of type false and null; however, parameter $filename of readfile() 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

599
            @readfile(/** @scrutinizer ignore-type */ $SourceFilename);
Loading history...
600
            exit;
601
        }
602
        $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

602
        $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...
603
        break;
604
    }
605
    $phpThumb->DebugMessage('Not passing "' . $SourceFilename . '" through directly because getimagesize() failed', __FILE__, __LINE__);
606
    break;
607
    break;
608
}
609
610
////////////////////////////////////////////////////////////////
611
// Debug output, to try and help me diagnose problems
612
$phpThumb->DebugTimingMessage('phpThumbDebug[5]', __FILE__, __LINE__);
613
if (isset($_GET['phpThumbDebug']) && ('5' == $_GET['phpThumbDebug'])) {
614
    $phpThumb->phpThumbDebug();
615
}
616
////////////////////////////////////////////////////////////////
617
618
// check to see if file already exists in cache, and output it with no processing if it does
619
$phpThumb->SetCacheFilename();
620
if (@is_readable($phpThumb->cache_filename)) {
621
    RedirectToCachedFile();
622
} else {
623
    $phpThumb->DebugMessage('Cached file "' . $phpThumb->cache_filename . '" does not exist, processing as normal', __FILE__, __LINE__);
624
}
625
626
////////////////////////////////////////////////////////////////
627
// Debug output, to try and help me diagnose problems
628
$phpThumb->DebugTimingMessage('phpThumbDebug[6]', __FILE__, __LINE__);
629
if (isset($_GET['phpThumbDebug']) && ('6' == $_GET['phpThumbDebug'])) {
630
    $phpThumb->phpThumbDebug();
631
}
632
////////////////////////////////////////////////////////////////
633
634
if ($phpThumb->rawImageData) {
635
    // great
636
} elseif (!empty($_GET['new'])) {
637
    // generate a blank image resource of the specified size/background color/opacity
638
    if (($phpThumb->w <= 0) || ($phpThumb->h <= 0)) {
639
        $phpThumb->ErrorImage('"w" and "h" parameters required for "new"');
640
    }
641
    @list($bghexcolor, $opacity) = explode('|', $_GET['new']);
642
    if (!phpthumb_functions::IsHexColor($bghexcolor)) {
643
        $phpThumb->ErrorImage('BGcolor parameter for "new" is not valid');
644
    }
645
    $opacity = (mb_strlen($opacity) ? $opacity : 100);
646
    if ($phpThumb->gdimg_source = phpthumb_functions::ImageCreateFunction($phpThumb->w, $phpThumb->h)) {
647
        $alpha = (100 - min(100, max(0, $opacity))) * 1.27;
648
        if ($alpha) {
649
            $phpThumb->setParameter('is_alpha', true);
650
            imagealphablending($phpThumb->gdimg_source, false);
651
            imagesavealpha($phpThumb->gdimg_source, true);
652
        }
653
        $new_background_color = phpthumb_functions::ImageHexColorAllocate($phpThumb->gdimg_source, $bghexcolor, false, $alpha);
654
        imagefilledrectangle($phpThumb->gdimg_source, 0, 0, $phpThumb->w, $phpThumb->h, $new_background_color);
655
    } else {
656
        $phpThumb->ErrorImage('failed to create "new" image (' . $phpThumb->w . 'x' . $phpThumb->h . ')');
657
    }
658
} elseif (!$phpThumb->src) {
659
    $phpThumb->ErrorImage('Usage: ' . $_SERVER['PHP_SELF'] . '?src=/path/and/filename.jpg' . "\n" . 'read Usage comments for details');
660
} elseif (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
661
    if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
662
        $phpThumb->DebugMessage('$phpThumb->src (' . $phpThumb->src . ') is remote image, attempting to download', __FILE__, __LINE__);
663
        if ($phpThumb->config_http_user_agent) {
664
            $phpThumb->DebugMessage('Setting "user_agent" to "' . $phpThumb->config_http_user_agent . '"', __FILE__, __LINE__);
665
            ini_set('user_agent', $phpThumb->config_http_user_agent);
666
        }
667
        $cleanedupurl = phpthumb_functions::CleanUpURLencoding($phpThumb->src);
668
        $phpThumb->DebugMessage('CleanUpURLencoding(' . $phpThumb->src . ') returned "' . $cleanedupurl . '"', __FILE__, __LINE__);
669
        $phpThumb->src = $cleanedupurl;
670
        unset($cleanedupurl);
671
        if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
672
            $phpThumb->DebugMessage('SafeURLread(' . $phpThumb->src . ') succeeded' . ($error ? ' with messsages: "' . $error . '"' : ''), __FILE__, __LINE__);
673
            $phpThumb->DebugMessage('Setting source data from URL "' . $phpThumb->src . '"', __FILE__, __LINE__);
674
            $phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
675
        } else {
676
            $phpThumb->ErrorImage($error);
677
        }
678
    } else {
679
        $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "' . $protocol_matches[1] . '" is not');
680
    }
681
}
682
683
////////////////////////////////////////////////////////////////
684
// Debug output, to try and help me diagnose problems
685
$phpThumb->DebugTimingMessage('phpThumbDebug[7]', __FILE__, __LINE__);
686
if (isset($_GET['phpThumbDebug']) && ('7' == $_GET['phpThumbDebug'])) {
687
    $phpThumb->phpThumbDebug();
688
}
689
////////////////////////////////////////////////////////////////
690
691
$phpThumb->GenerateThumbnail();
692
693
////////////////////////////////////////////////////////////////
694
// Debug output, to try and help me diagnose problems
695
$phpThumb->DebugTimingMessage('phpThumbDebug[8]', __FILE__, __LINE__);
696
if (isset($_GET['phpThumbDebug']) && ('8' == $_GET['phpThumbDebug'])) {
697
    $phpThumb->phpThumbDebug();
698
}
699
////////////////////////////////////////////////////////////////
700
701
if (!empty($phpThumb->config_high_security_enabled) && !empty($_GET['nocache'])) {
702
    // cache disabled, don't write cachefile
703
} else {
704
    phpthumb_functions::EnsureDirectoryExists(dirname($phpThumb->cache_filename));
705
    if (is_writable(dirname($phpThumb->cache_filename))
706
        || (file_exists($phpThumb->cache_filename)
707
            && is_writable($phpThumb->cache_filename))) {
708
        $phpThumb->CleanUpCacheDirectory();
709
        if ($phpThumb->RenderToFile($phpThumb->cache_filename) && is_readable($phpThumb->cache_filename)) {
710
            chmod($phpThumb->cache_filename, 0644);
711
            RedirectToCachedFile();
712
        } else {
713
            $phpThumb->DebugMessage('Failed: RenderToFile(' . $phpThumb->cache_filename . ')', __FILE__, __LINE__);
714
        }
715
    } else {
716
        $phpThumb->DebugMessage('Cannot write to $phpThumb->cache_filename (' . $phpThumb->cache_filename . ') because that directory (' . \dirname($phpThumb->cache_filename) . ') is not writable', __FILE__, __LINE__);
717
    }
718
}
719
720
////////////////////////////////////////////////////////////////
721
// Debug output, to try and help me diagnose problems
722
$phpThumb->DebugTimingMessage('phpThumbDebug[9]', __FILE__, __LINE__);
723
if (isset($_GET['phpThumbDebug']) && ('9' == $_GET['phpThumbDebug'])) {
724
    $phpThumb->phpThumbDebug();
725
}
726
////////////////////////////////////////////////////////////////
727
728
if (!$phpThumb->OutputThumbnail()) {
729
    $phpThumb->ErrorImage('Error in OutputThumbnail():' . "\n" . $phpThumb->debugmessages[count($phpThumb->debugmessages) - 1]);
730
}
731
732
////////////////////////////////////////////////////////////////
733
// Debug output, to try and help me diagnose problems
734
$phpThumb->DebugTimingMessage('phpThumbDebug[10]', __FILE__, __LINE__);
735
if (isset($_GET['phpThumbDebug']) && ('10' == $_GET['phpThumbDebug'])) {
736
    $phpThumb->phpThumbDebug();
737
}
738
////////////////////////////////////////////////////////////////
739