PageRenderTime 39ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/phpthumb/phpThumb.php

http://github.com/thibaud-rohmer/PhotoShow
PHP | 642 lines | 478 code | 80 blank | 84 comment | 174 complexity | 926ef9af19abdc8255c0dde3ee0fbfc4 MD5 | raw file
  1. <?php
  2. //////////////////////////////////////////////////////////////
  3. // phpThumb() by James Heinrich <info@silisoftware.com> //
  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. error_reporting(E_ALL);
  13. ini_set('display_errors', '1');
  14. ini_set('magic_quotes_runtime', '0');
  15. if (ini_get('magic_quotes_runtime')) {
  16. die('"magic_quotes_runtime" is set in php.ini, cannot run phpThumb with this enabled');
  17. }
  18. $starttime = array_sum(explode(' ', microtime())); // could be called as microtime(true) for PHP 5.0.0+
  19. // this script relies on the superglobal arrays, fake it here for old PHP versions
  20. if (phpversion() < '4.1.0') {
  21. $_SERVER = $HTTP_SERVER_VARS;
  22. $_GET = $HTTP_GET_VARS;
  23. }
  24. function SendSaveAsFileHeaderIfNeeded() {
  25. if (headers_sent()) {
  26. return false;
  27. }
  28. global $phpThumb;
  29. $downloadfilename = phpthumb_functions::SanitizeFilename(!empty($_GET['sia']) ? $_GET['sia'] : (!empty($_GET['down']) ? $_GET['down'] : 'phpThumb_generated_thumbnail'.(!empty($_GET['f']) ? $_GET['f'] : 'jpg')));
  30. if (!empty($downloadfilename)) {
  31. $phpThumb->DebugMessage('SendSaveAsFileHeaderIfNeeded() sending header: Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"', __FILE__, __LINE__);
  32. header('Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
  33. }
  34. return true;
  35. }
  36. function PasswordStrength($password) {
  37. $strength = 0;
  38. $strength += strlen(preg_replace('#[^a-z]#', '', $password)) * 0.5; // lowercase characters are weak
  39. $strength += strlen(preg_replace('#[^A-Z]#', '', $password)) * 0.8; // uppercase characters are somewhat better
  40. $strength += strlen(preg_replace('#[^0-9]#', '', $password)) * 1.0; // numbers are somewhat better
  41. $strength += strlen(preg_replace('#[a-zA-Z0-9]#', '', $password)) * 2.0; // other non-alphanumeric characters are best
  42. return $strength;
  43. }
  44. function RedirectToCachedFile() {
  45. global $phpThumb;
  46. $nice_cachefile = str_replace(DIRECTORY_SEPARATOR, '/', $phpThumb->cache_filename);
  47. $nice_docroot = str_replace(DIRECTORY_SEPARATOR, '/', rtrim($phpThumb->config_document_root, '/\\'));
  48. $parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
  49. $nModified = filemtime($phpThumb->cache_filename);
  50. if ($phpThumb->config_nooffsitelink_enabled && !empty($_SERVER['HTTP_REFERER']) && !in_array(@$parsed_url['host'], $phpThumb->config_nooffsitelink_valid_domains)) {
  51. $phpThumb->DebugMessage('Would have used cached (image/'.$phpThumb->thumbnailFormat.') file "'.$phpThumb->cache_filename.'" (Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT), but skipping because $_SERVER[HTTP_REFERER] ('.@$_SERVER['HTTP_REFERER'].') is not in $phpThumb->config_nooffsitelink_valid_domains ('.implode(';', $phpThumb->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
  52. } elseif ($phpThumb->phpThumbDebug) {
  53. $phpThumb->DebugTimingMessage('skipped using cached image', __FILE__, __LINE__);
  54. $phpThumb->DebugMessage('Would have used cached file, but skipping due to phpThumbDebug', __FILE__, __LINE__);
  55. $phpThumb->DebugMessage('* Would have sent headers (1): Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT', __FILE__, __LINE__);
  56. if ($getimagesize = @GetImageSize($phpThumb->cache_filename)) {
  57. $phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
  58. }
  59. if (preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
  60. $phpThumb->DebugMessage('* Would have sent headers (3): Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])), __FILE__, __LINE__);
  61. } else {
  62. $phpThumb->DebugMessage('* Would have sent data: readfile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
  63. }
  64. } else {
  65. if (headers_sent()) {
  66. $phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
  67. exit;
  68. }
  69. SendSaveAsFileHeaderIfNeeded();
  70. header('Cache-Control: private');
  71. header('Pragma: private');
  72. header('Expires: '.date(DATE_RFC822, strtotime(' 1 day')));
  73. if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
  74. header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT', true, 304);
  75. exit;
  76. }
  77. if ($getimagesize = @GetImageSize($phpThumb->cache_filename)) {
  78. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]));
  79. } elseif (preg_match('#\\.ico$#i', $phpThumb->cache_filename)) {
  80. header('Content-Type: image/x-icon');
  81. }
  82. header('Content-Length: '.filesize($phpThumb->cache_filename));
  83. if (empty($phpThumb->config_cache_force_passthru) && preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
  84. header('Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])));
  85. } else {
  86. @readfile($phpThumb->cache_filename);
  87. }
  88. exit;
  89. }
  90. return true;
  91. }
  92. // instantiate a new phpThumb() object
  93. ob_start();
  94. if (!include_once(dirname(__FILE__).'/phpthumb.class.php')) {
  95. ob_end_flush();
  96. die('failed to include_once("'.realpath(dirname(__FILE__).'/phpthumb.class.php').'")');
  97. }
  98. ob_end_clean();
  99. $phpThumb = new phpThumb();
  100. $phpThumb->DebugTimingMessage('phpThumb.php start', __FILE__, __LINE__, $starttime);
  101. $phpThumb->SetParameter('config_error_die_on_error', true);
  102. if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
  103. set_time_limit(60); // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
  104. }
  105. // phpThumbDebug[0] used to be here, but may reveal too much
  106. // info when high_security_mode should be enabled (not set yet)
  107. if (file_exists(dirname(__FILE__).'/phpThumb.config.php')) {
  108. ob_start();
  109. if (include_once(dirname(__FILE__).'/phpThumb.config.php')) {
  110. // great
  111. } else {
  112. ob_end_flush();
  113. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  114. $phpThumb->ErrorImage('failed to include_once('.dirname(__FILE__).'/phpThumb.config.php) - realpath="'.realpath(dirname(__FILE__).'/phpThumb.config.php').'"');
  115. }
  116. ob_end_clean();
  117. } elseif (file_exists(dirname(__FILE__).'/phpThumb.config.php.default')) {
  118. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  119. $phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
  120. } else {
  121. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  122. $phpThumb->ErrorImage('failed to include_once('.dirname(__FILE__).'/phpThumb.config.php) - realpath="'.realpath(dirname(__FILE__).'/phpThumb.config.php').'"');
  123. }
  124. if (!empty($PHPTHUMB_CONFIG)) {
  125. foreach ($PHPTHUMB_CONFIG as $key => $value) {
  126. $keyname = 'config_'.$key;
  127. $phpThumb->setParameter($keyname, $value);
  128. if (!preg_match('#(password|mysql)#i', $key)) {
  129. $phpThumb->DebugMessage('setParameter('.$keyname.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
  130. }
  131. }
  132. if (!$phpThumb->config_disable_debug) {
  133. // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
  134. $_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, intval($_GET['phpThumbDebug'])) : 9);
  135. $phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
  136. }
  137. } else {
  138. $phpThumb->DebugMessage('$PHPTHUMB_CONFIG is empty', __FILE__, __LINE__);
  139. }
  140. if (empty($phpThumb->config_disable_pathinfo_parsing) && (empty($_GET) || isset($_GET['phpThumbDebug'])) && !empty($_SERVER['PATH_INFO'])) {
  141. $_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);
  142. $args = explode(';', substr($_SERVER['PATH_INFO'], 1));
  143. $phpThumb->DebugMessage('PATH_INFO.$args set to ('.implode(')(', $args).')', __FILE__, __LINE__);
  144. if (!empty($args)) {
  145. $_GET['src'] = @$args[count($args) - 1];
  146. $phpThumb->DebugMessage('PATH_INFO."src" = "'.$_GET['src'].'"', __FILE__, __LINE__);
  147. if (preg_match('#^new\=([a-z0-9]+)#i', $_GET['src'], $matches)) {
  148. unset($_GET['src']);
  149. $_GET['new'] = $matches[1];
  150. }
  151. }
  152. if (preg_match('#^([0-9]*)x?([0-9]*)$#i', @$args[count($args) - 2], $matches)) {
  153. $_GET['w'] = $matches[1];
  154. $_GET['h'] = $matches[2];
  155. $phpThumb->DebugMessage('PATH_INFO."w"x"h" set to "'.$_GET['w'].'"x"'.$_GET['h'].'"', __FILE__, __LINE__);
  156. }
  157. for ($i = 0; $i < count($args) - 2; $i++) {
  158. @list($key, $value) = explode('=', @$args[$i]);
  159. if (substr($key, -2) == '[]') {
  160. $array_key_name = substr($key, 0, -2);
  161. $_GET[$array_key_name][] = $value;
  162. $phpThumb->DebugMessage('PATH_INFO."'.$array_key_name.'[]" = "'.$value.'"', __FILE__, __LINE__);
  163. } else {
  164. $_GET[$key] = $value;
  165. $phpThumb->DebugMessage('PATH_INFO."'.$key.'" = "'.$value.'"', __FILE__, __LINE__);
  166. }
  167. }
  168. }
  169. if (!empty($phpThumb->config_high_security_enabled)) {
  170. if (empty($_GET['hash'])) {
  171. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  172. $phpThumb->ErrorImage('ERROR: missing hash');
  173. } elseif (PasswordStrength($phpThumb->config_high_security_password) < 20) {
  174. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  175. $phpThumb->ErrorImage('ERROR: $PHPTHUMB_CONFIG[high_security_password] is not complex enough');
  176. } elseif ($_GET['hash'] != md5(str_replace($phpThumb->config_high_security_url_separator.'hash='.$_GET['hash'], '', $_SERVER['QUERY_STRING']).$phpThumb->config_high_security_password)) {
  177. header('HTTP/1.0 403 Forbidden');
  178. sleep(10); // deliberate delay to discourage password-guessing
  179. $phpThumb->ErrorImage('ERROR: invalid hash');
  180. }
  181. }
  182. ////////////////////////////////////////////////////////////////
  183. // Debug output, to try and help me diagnose problems
  184. $phpThumb->DebugTimingMessage('phpThumbDebug[0]', __FILE__, __LINE__);
  185. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '0')) {
  186. $phpThumb->phpThumbDebug();
  187. }
  188. ////////////////////////////////////////////////////////////////
  189. // returned the fixed string if the evil "magic_quotes_gpc" setting is on
  190. if (get_magic_quotes_gpc()) {
  191. // deprecated: 'err', 'file', 'goto',
  192. $RequestVarsToStripSlashes = array('src', 'wmf', 'down');
  193. foreach ($RequestVarsToStripSlashes as $key) {
  194. if (isset($_GET[$key])) {
  195. if (is_string($_GET[$key])) {
  196. $_GET[$key] = stripslashes($_GET[$key]);
  197. } else {
  198. unset($_GET[$key]);
  199. }
  200. }
  201. }
  202. }
  203. if (empty($_SERVER['PATH_INFO']) && empty($_SERVER['QUERY_STRING'])) {
  204. $phpThumb->config_disable_debug = false; // otherwise error message won't print
  205. $phpThumb->ErrorImage('ERROR: no parameters specified');
  206. }
  207. if (!empty($_GET['src']) && isset($_GET['md5s']) && empty($_GET['md5s'])) {
  208. if (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
  209. if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
  210. if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
  211. $md5s = md5($rawImageData);
  212. }
  213. } else {
  214. $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
  215. }
  216. } else {
  217. $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($_GET['src']);
  218. if (is_readable($SourceFilename)) {
  219. $md5s = phpthumb_functions::md5_file_safe($SourceFilename);
  220. } else {
  221. $phpThumb->ErrorImage('ERROR: "'.$SourceFilename.'" cannot be read');
  222. }
  223. }
  224. if (!empty($_SERVER['HTTP_REFERER'])) {
  225. $phpThumb->ErrorImage('&md5s='.$md5s);
  226. } else {
  227. die('&md5s='.$md5s);
  228. }
  229. }
  230. if (!empty($_GET['src']) && empty($phpThumb->config_allow_local_http_src) && preg_match('#^http://'.@$_SERVER['HTTP_HOST'].'(.+)#i', $_GET['src'], $matches)) {
  231. $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');
  232. }
  233. ////////////////////////////////////////////////////////////////
  234. // Debug output, to try and help me diagnose problems
  235. $phpThumb->DebugTimingMessage('phpThumbDebug[1]', __FILE__, __LINE__);
  236. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '1')) {
  237. $phpThumb->phpThumbDebug();
  238. }
  239. ////////////////////////////////////////////////////////////////
  240. $parsed_url_referer = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
  241. if ($phpThumb->config_nooffsitelink_require_refer && !in_array(@$parsed_url_referer['host'], $phpThumb->config_nohotlink_valid_domains)) {
  242. $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'));
  243. }
  244. $parsed_url_src = phpthumb_functions::ParseURLbetter(@$_GET['src']);
  245. 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)) {
  246. $phpThumb->ErrorImage($phpThumb->config_nohotlink_text_message);
  247. }
  248. if ($phpThumb->config_mysql_query) {
  249. if ($cid = @mysql_connect($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password)) {
  250. if (@mysql_select_db($phpThumb->config_mysql_database, $cid)) {
  251. if ($result = @mysql_query($phpThumb->config_mysql_query, $cid)) {
  252. if ($row = @mysql_fetch_array($result)) {
  253. mysql_free_result($result);
  254. mysql_close($cid);
  255. $phpThumb->setSourceData($row[0]);
  256. unset($row);
  257. } else {
  258. mysql_free_result($result);
  259. mysql_close($cid);
  260. $phpThumb->ErrorImage('no matching data in database.');
  261. }
  262. } else {
  263. mysql_close($cid);
  264. $phpThumb->ErrorImage('Error in MySQL query: "'.mysql_error($cid).'"');
  265. }
  266. } else {
  267. mysql_close($cid);
  268. $phpThumb->ErrorImage('cannot select MySQL database: "'.mysql_error($cid).'"');
  269. }
  270. } else {
  271. $phpThumb->ErrorImage('cannot connect to MySQL server');
  272. }
  273. unset($_GET['id']);
  274. }
  275. ////////////////////////////////////////////////////////////////
  276. // Debug output, to try and help me diagnose problems
  277. $phpThumb->DebugTimingMessage('phpThumbDebug[2]', __FILE__, __LINE__);
  278. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '2')) {
  279. $phpThumb->phpThumbDebug();
  280. }
  281. ////////////////////////////////////////////////////////////////
  282. $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = (bool) ($phpThumb->config_cache_default_only_suffix && (strpos($phpThumb->config_cache_default_only_suffix, '*') !== false));
  283. // deprecated: 'err', 'file', 'goto',
  284. $allowedGETparameters = array('src', 'new', 'w', 'h', 'wp', 'hp', 'wl', 'hl', 'ws', 'hs', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'zc', 'bc', 'bg', 'bgt', 'fltr', 'xto', 'ra', 'ar', 'aoe', 'far', 'iar', 'maxb', 'down', 'phpThumbDebug', 'hash', 'md5s', 'sfn', 'dpi', 'sia', 'nocache');
  285. foreach ($_GET as $key => $value) {
  286. if (!empty($PHPTHUMB_DEFAULTS_DISABLEGETPARAMS) && ($key != 'src')) {
  287. // disabled, do not set parameter
  288. $phpThumb->DebugMessage('ignoring $_GET['.$key.'] because of $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS', __FILE__, __LINE__);
  289. } elseif (in_array($key, $allowedGETparameters)) {
  290. $phpThumb->DebugMessage('setParameter('.$key.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
  291. $phpThumb->setParameter($key, $value);
  292. } else {
  293. $phpThumb->ErrorImage('Forbidden parameter: '.$key);
  294. }
  295. }
  296. if (!empty($PHPTHUMB_DEFAULTS) && is_array($PHPTHUMB_DEFAULTS)) {
  297. $phpThumb->DebugMessage('setting $PHPTHUMB_DEFAULTS['.implode(';', array_keys($PHPTHUMB_DEFAULTS)).']', __FILE__, __LINE__);
  298. foreach ($PHPTHUMB_DEFAULTS as $key => $value) {
  299. 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
  300. $_GET[$key] = $value;
  301. $phpThumb->DebugMessage('PHPTHUMB_DEFAULTS assigning ('.(is_array($value) ? print_r($value, true) : $value).') to $_GET['.$key.']', __FILE__, __LINE__);
  302. }
  303. }
  304. }
  305. ////////////////////////////////////////////////////////////////
  306. // Debug output, to try and help me diagnose problems
  307. $phpThumb->DebugTimingMessage('phpThumbDebug[3]', __FILE__, __LINE__);
  308. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '3')) {
  309. $phpThumb->phpThumbDebug();
  310. }
  311. ////////////////////////////////////////////////////////////////
  312. //if (!@$_GET['phpThumbDebug'] && !is_file($phpThumb->sourceFilename) && !phpthumb_functions::gd_version()) {
  313. // if (!headers_sent()) {
  314. // // base64-encoded error image in GIF format
  315. // $ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7';
  316. // header('Content-Type: image/gif');
  317. // echo base64_decode($ERROR_NOGD);
  318. // } else {
  319. // echo '*** ERROR: No PHP-GD support available ***';
  320. // }
  321. // exit;
  322. //}
  323. // check to see if file can be output from source with no processing or caching
  324. $CanPassThroughDirectly = true;
  325. if ($phpThumb->rawImageData) {
  326. // data from SQL, should be fine
  327. } elseif (preg_match('#^http\://[^\\?&]+\\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
  328. // assume is ok to passthru if no other parameters specified
  329. } elseif (preg_match('#^(f|ht)tp\://#i', $phpThumb->src)) {
  330. $phpThumb->DebugMessage('$CanPassThroughDirectly=false because preg_match("#^(f|ht)tp\://#i", '.$phpThumb->src.')', __FILE__, __LINE__);
  331. $CanPassThroughDirectly = false;
  332. } elseif (!@is_readable($phpThumb->sourceFilename)) {
  333. $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_readable('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
  334. $CanPassThroughDirectly = false;
  335. } elseif (!@is_file($phpThumb->sourceFilename)) {
  336. $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_file('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
  337. $CanPassThroughDirectly = false;
  338. }
  339. foreach ($_GET as $key => $value) {
  340. switch ($key) {
  341. case 'src':
  342. // allowed
  343. break;
  344. case 'w':
  345. case 'h':
  346. // might be OK if exactly matches original
  347. if (preg_match('#^http\://[^\\?&]+\\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
  348. // assume it is not ok for direct-passthru of remote image
  349. $CanPassThroughDirectly = false;
  350. }
  351. break;
  352. case 'phpThumbDebug':
  353. // handled in direct-passthru code
  354. break;
  355. default:
  356. // all other parameters will cause some processing,
  357. // therefore cannot pass through original image unmodified
  358. $CanPassThroughDirectly = false;
  359. $UnAllowedGET[] = $key;
  360. break;
  361. }
  362. }
  363. if (!empty($UnAllowedGET)) {
  364. $phpThumb->DebugMessage('$CanPassThroughDirectly=false because $_GET['.implode(';', array_unique($UnAllowedGET)).'] are set', __FILE__, __LINE__);
  365. }
  366. ////////////////////////////////////////////////////////////////
  367. // Debug output, to try and help me diagnose problems
  368. $phpThumb->DebugTimingMessage('phpThumbDebug[4]', __FILE__, __LINE__);
  369. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '4')) {
  370. $phpThumb->phpThumbDebug();
  371. }
  372. ////////////////////////////////////////////////////////////////
  373. $phpThumb->DebugMessage('$CanPassThroughDirectly="'.intval($CanPassThroughDirectly).'" && $phpThumb->src="'.$phpThumb->src.'"', __FILE__, __LINE__);
  374. while ($CanPassThroughDirectly && $phpThumb->src) {
  375. // no parameters set, passthru
  376. if (preg_match('#^http\://[^\\?&]+\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
  377. $phpThumb->DebugMessage('Passing HTTP source through directly as Location: redirect ('.$phpThumb->src.')', __FILE__, __LINE__);
  378. header('Location: '.$phpThumb->src);
  379. exit;
  380. }
  381. $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($phpThumb->src);
  382. // security and size checks
  383. if ($phpThumb->getimagesizeinfo = @GetImageSize($SourceFilename)) {
  384. $phpThumb->DebugMessage('Direct passthru GetImageSize() returned [w='.$phpThumb->getimagesizeinfo[0].';h='.$phpThumb->getimagesizeinfo[1].';t='.$phpThumb->getimagesizeinfo[2].']', __FILE__, __LINE__);
  385. if (!@$_GET['w'] && !@$_GET['wp'] && !@$_GET['wl'] && !@$_GET['ws'] && !@$_GET['h'] && !@$_GET['hp'] && !@$_GET['hl'] && !@$_GET['hs']) {
  386. // no resizing needed
  387. $phpThumb->DebugMessage('Passing "'.$SourceFilename.'" through directly, no resizing required ("'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'")', __FILE__, __LINE__);
  388. } elseif (($phpThumb->getimagesizeinfo[0] <= @$_GET['w']) && ($phpThumb->getimagesizeinfo[1] <= @$_GET['h']) && ((@$_GET['w'] == $phpThumb->getimagesizeinfo[0]) || (@$_GET['h'] == $phpThumb->getimagesizeinfo[1]))) {
  389. // image fits into 'w'x'h' box, and at least one dimension matches exactly, therefore no resizing needed
  390. $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__);
  391. } else {
  392. $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__);
  393. break;
  394. }
  395. switch ($phpThumb->getimagesizeinfo[2]) {
  396. case 1: // GIF
  397. case 2: // JPG
  398. case 3: // PNG
  399. // great, let it through
  400. break;
  401. default:
  402. // browser probably can't handle format, remangle it to JPEG/PNG/GIF
  403. $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because $phpThumb->getimagesizeinfo[2] = "'.$phpThumb->getimagesizeinfo[2].'"', __FILE__, __LINE__);
  404. break 2;
  405. }
  406. $ImageCreateFunctions = array(1=>'ImageCreateFromGIF', 2=>'ImageCreateFromJPEG', 3=>'ImageCreateFromPNG');
  407. $theImageCreateFunction = @$ImageCreateFunctions[$phpThumb->getimagesizeinfo[2]];
  408. if ($phpThumb->config_disable_onlycreateable_passthru || (function_exists($theImageCreateFunction) && ($dummyImage = @$theImageCreateFunction($SourceFilename)))) {
  409. // great
  410. if (@is_resource($dummyImage)) {
  411. unset($dummyImage);
  412. }
  413. if (headers_sent()) {
  414. $phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
  415. exit;
  416. }
  417. if (@$_GET['phpThumbDebug']) {
  418. $phpThumb->DebugTimingMessage('skipped direct $SourceFilename passthru', __FILE__, __LINE__);
  419. $phpThumb->DebugMessage('Would have passed "'.$SourceFilename.'" through directly, but skipping due to phpThumbDebug', __FILE__, __LINE__);
  420. break;
  421. }
  422. SendSaveAsFileHeaderIfNeeded();
  423. header('Last-Modified: '.gmdate('D, d M Y H:i:s', @filemtime($SourceFilename)).' GMT');
  424. if ($contentType = phpthumb_functions::ImageTypeToMIMEtype(@$phpThumb->getimagesizeinfo[2])) {
  425. header('Content-Type: '.$contentType);
  426. }
  427. @readfile($SourceFilename);
  428. exit;
  429. } else {
  430. $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because ($phpThumb->config_disable_onlycreateable_passthru = "'.$phpThumb->config_disable_onlycreateable_passthru.'") and '.$theImageCreateFunction.'() failed', __FILE__, __LINE__);
  431. break;
  432. }
  433. } else {
  434. $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because GetImageSize() failed', __FILE__, __LINE__);
  435. break;
  436. }
  437. break;
  438. }
  439. ////////////////////////////////////////////////////////////////
  440. // Debug output, to try and help me diagnose problems
  441. $phpThumb->DebugTimingMessage('phpThumbDebug[5]', __FILE__, __LINE__);
  442. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '5')) {
  443. $phpThumb->phpThumbDebug();
  444. }
  445. ////////////////////////////////////////////////////////////////
  446. // check to see if file already exists in cache, and output it with no processing if it does
  447. $phpThumb->SetCacheFilename();
  448. if (@is_readable($phpThumb->cache_filename)) {
  449. RedirectToCachedFile();
  450. } else {
  451. $phpThumb->DebugMessage('Cached file "'.$phpThumb->cache_filename.'" does not exist, processing as normal', __FILE__, __LINE__);
  452. }
  453. ////////////////////////////////////////////////////////////////
  454. // Debug output, to try and help me diagnose problems
  455. $phpThumb->DebugTimingMessage('phpThumbDebug[6]', __FILE__, __LINE__);
  456. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '6')) {
  457. $phpThumb->phpThumbDebug();
  458. }
  459. ////////////////////////////////////////////////////////////////
  460. if ($phpThumb->rawImageData) {
  461. // great
  462. } elseif (!empty($_GET['new'])) {
  463. // generate a blank image resource of the specified size/background color/opacity
  464. if (($phpThumb->w <= 0) || ($phpThumb->h <= 0)) {
  465. $phpThumb->ErrorImage('"w" and "h" parameters required for "new"');
  466. }
  467. @list($bghexcolor, $opacity) = explode('|', $_GET['new']);
  468. if (!phpthumb_functions::IsHexColor($bghexcolor)) {
  469. $phpThumb->ErrorImage('BGcolor parameter for "new" is not valid');
  470. }
  471. $opacity = (strlen($opacity) ? $opacity : 100);
  472. if ($phpThumb->gdimg_source = phpthumb_functions::ImageCreateFunction($phpThumb->w, $phpThumb->h)) {
  473. $alpha = (100 - min(100, max(0, $opacity))) * 1.27;
  474. if ($alpha) {
  475. $phpThumb->setParameter('is_alpha', true);
  476. ImageAlphaBlending($phpThumb->gdimg_source, false);
  477. ImageSaveAlpha($phpThumb->gdimg_source, true);
  478. }
  479. $new_background_color = phpthumb_functions::ImageHexColorAllocate($phpThumb->gdimg_source, $bghexcolor, false, $alpha);
  480. ImageFilledRectangle($phpThumb->gdimg_source, 0, 0, $phpThumb->w, $phpThumb->h, $new_background_color);
  481. } else {
  482. $phpThumb->ErrorImage('failed to create "new" image ('.$phpThumb->w.'x'.$phpThumb->h.')');
  483. }
  484. } elseif (!$phpThumb->src) {
  485. $phpThumb->ErrorImage('Usage: '.$_SERVER['PHP_SELF'].'?src=/path/and/filename.jpg'."\n".'read Usage comments for details');
  486. } elseif (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
  487. if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
  488. $phpThumb->DebugMessage('$phpThumb->src ('.$phpThumb->src.') is remote image, attempting to download', __FILE__, __LINE__);
  489. if ($phpThumb->config_http_user_agent) {
  490. $phpThumb->DebugMessage('Setting "user_agent" to "'.$phpThumb->config_http_user_agent.'"', __FILE__, __LINE__);
  491. ini_set('user_agent', $phpThumb->config_http_user_agent);
  492. }
  493. $cleanedupurl = phpthumb_functions::CleanUpURLencoding($phpThumb->src);
  494. $phpThumb->DebugMessage('CleanUpURLencoding('.$phpThumb->src.') returned "'.$cleanedupurl.'"', __FILE__, __LINE__);
  495. $phpThumb->src = $cleanedupurl;
  496. unset($cleanedupurl);
  497. if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
  498. $phpThumb->DebugMessage('SafeURLread('.$phpThumb->src.') succeeded'.($error ? ' with messsages: "'.$error.'"' : ''), __FILE__, __LINE__);
  499. $phpThumb->DebugMessage('Setting source data from URL "'.$phpThumb->src.'"', __FILE__, __LINE__);
  500. $phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
  501. } else {
  502. $phpThumb->ErrorImage($error);
  503. }
  504. } else {
  505. $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
  506. }
  507. }
  508. ////////////////////////////////////////////////////////////////
  509. // Debug output, to try and help me diagnose problems
  510. $phpThumb->DebugTimingMessage('phpThumbDebug[7]', __FILE__, __LINE__);
  511. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '7')) {
  512. $phpThumb->phpThumbDebug();
  513. }
  514. ////////////////////////////////////////////////////////////////
  515. $phpThumb->GenerateThumbnail();
  516. ////////////////////////////////////////////////////////////////
  517. // Debug output, to try and help me diagnose problems
  518. $phpThumb->DebugTimingMessage('phpThumbDebug[8]', __FILE__, __LINE__);
  519. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '8')) {
  520. $phpThumb->phpThumbDebug();
  521. }
  522. ////////////////////////////////////////////////////////////////
  523. if (!empty($phpThumb->config_high_security_enabled) && !empty($_GET['nocache'])) {
  524. // cache disabled, don't write cachefile
  525. } else {
  526. phpthumb_functions::EnsureDirectoryExists(dirname($phpThumb->cache_filename));
  527. if (is_writable(dirname($phpThumb->cache_filename)) || (file_exists($phpThumb->cache_filename) && is_writable($phpThumb->cache_filename))) {
  528. $phpThumb->CleanUpCacheDirectory();
  529. if ($phpThumb->RenderToFile($phpThumb->cache_filename) && is_readable($phpThumb->cache_filename)) {
  530. chmod($phpThumb->cache_filename, 0644);
  531. RedirectToCachedFile();
  532. } else {
  533. $phpThumb->DebugMessage('Failed: RenderToFile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
  534. }
  535. } else {
  536. $phpThumb->DebugMessage('Cannot write to $phpThumb->cache_filename ('.$phpThumb->cache_filename.') because that directory ('.dirname($phpThumb->cache_filename).') is not writable', __FILE__, __LINE__);
  537. }
  538. }
  539. ////////////////////////////////////////////////////////////////
  540. // Debug output, to try and help me diagnose problems
  541. $phpThumb->DebugTimingMessage('phpThumbDebug[9]', __FILE__, __LINE__);
  542. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '9')) {
  543. $phpThumb->phpThumbDebug();
  544. }
  545. ////////////////////////////////////////////////////////////////
  546. if (!$phpThumb->OutputThumbnail()) {
  547. $phpThumb->ErrorImage('Error in OutputThumbnail():'."\n".$phpThumb->debugmessages[(count($phpThumb->debugmessages) - 1)]);
  548. }
  549. ////////////////////////////////////////////////////////////////
  550. // Debug output, to try and help me diagnose problems
  551. $phpThumb->DebugTimingMessage('phpThumbDebug[10]', __FILE__, __LINE__);
  552. if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '10')) {
  553. $phpThumb->phpThumbDebug();
  554. }
  555. ////////////////////////////////////////////////////////////////
  556. ?>