File indexing completed on 2025-02-02 05:43:44
0001 <?php 0002 0003 /** 0004 * Implements data: URI for base64 encoded images supported by GD. 0005 */ 0006 class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme 0007 { 0008 /** 0009 * @type bool 0010 */ 0011 public $browsable = true; 0012 0013 /** 0014 * @type array 0015 */ 0016 public $allowed_types = array( 0017 // you better write validation code for other types if you 0018 // decide to allow them 0019 'image/jpeg' => true, 0020 'image/gif' => true, 0021 'image/png' => true, 0022 ); 0023 // this is actually irrelevant since we only write out the path 0024 // component 0025 /** 0026 * @type bool 0027 */ 0028 public $may_omit_host = true; 0029 0030 /** 0031 * @param HTMLPurifier_URI $uri 0032 * @param HTMLPurifier_Config $config 0033 * @param HTMLPurifier_Context $context 0034 * @return bool 0035 */ 0036 public function doValidate(&$uri, $config, $context) 0037 { 0038 $result = explode(',', $uri->path, 2); 0039 $is_base64 = false; 0040 $charset = null; 0041 $content_type = null; 0042 if (count($result) == 2) { 0043 list($metadata, $data) = $result; 0044 // do some legwork on the metadata 0045 $metas = explode(';', $metadata); 0046 while (!empty($metas)) { 0047 $cur = array_shift($metas); 0048 if ($cur == 'base64') { 0049 $is_base64 = true; 0050 break; 0051 } 0052 if (substr($cur, 0, 8) == 'charset=') { 0053 // doesn't match if there are arbitrary spaces, but 0054 // whatever dude 0055 if ($charset !== null) { 0056 continue; 0057 } // garbage 0058 $charset = substr($cur, 8); // not used 0059 } else { 0060 if ($content_type !== null) { 0061 continue; 0062 } // garbage 0063 $content_type = $cur; 0064 } 0065 } 0066 } else { 0067 $data = $result[0]; 0068 } 0069 if ($content_type !== null && empty($this->allowed_types[$content_type])) { 0070 return false; 0071 } 0072 if ($charset !== null) { 0073 // error; we don't allow plaintext stuff 0074 $charset = null; 0075 } 0076 $data = rawurldecode($data); 0077 if ($is_base64) { 0078 $raw_data = base64_decode($data); 0079 } else { 0080 $raw_data = $data; 0081 } 0082 if ( strlen($raw_data) < 12 ) { 0083 // error; exif_imagetype throws exception with small files, 0084 // and this likely indicates a corrupt URI/failed parse anyway 0085 return false; 0086 } 0087 // XXX probably want to refactor this into a general mechanism 0088 // for filtering arbitrary content types 0089 if (function_exists('sys_get_temp_dir')) { 0090 $file = tempnam(sys_get_temp_dir(), ""); 0091 } else { 0092 $file = tempnam("/tmp", ""); 0093 } 0094 file_put_contents($file, $raw_data); 0095 if (function_exists('exif_imagetype')) { 0096 $image_code = exif_imagetype($file); 0097 unlink($file); 0098 } elseif (function_exists('getimagesize')) { 0099 set_error_handler(array($this, 'muteErrorHandler')); 0100 $info = getimagesize($file); 0101 restore_error_handler(); 0102 unlink($file); 0103 if ($info == false) { 0104 return false; 0105 } 0106 $image_code = $info[2]; 0107 } else { 0108 trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR); 0109 } 0110 $real_content_type = image_type_to_mime_type($image_code); 0111 if ($real_content_type != $content_type) { 0112 // we're nice guys; if the content type is something else we 0113 // support, change it over 0114 if (empty($this->allowed_types[$real_content_type])) { 0115 return false; 0116 } 0117 $content_type = $real_content_type; 0118 } 0119 // ok, it's kosher, rewrite what we need 0120 $uri->userinfo = null; 0121 $uri->host = null; 0122 $uri->port = null; 0123 $uri->fragment = null; 0124 $uri->query = null; 0125 $uri->path = "$content_type;base64," . base64_encode($raw_data); 0126 return true; 0127 } 0128 0129 /** 0130 * @param int $errno 0131 * @param string $errstr 0132 */ 0133 public function muteErrorHandler($errno, $errstr) 0134 { 0135 } 0136 }