HTMLPurifier 4.4.0
/home/ezyang/Dev/htmlpurifier/library/HTMLPurifier/URIScheme/data.php
Go to the documentation of this file.
00001 <?php
00002 
00006 class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme {
00007 
00008     public $browsable = true;
00009     public $allowed_types = array(
00010         // you better write validation code for other types if you
00011         // decide to allow them
00012         'image/jpeg' => true,
00013         'image/gif' => true,
00014         'image/png' => true,
00015         );
00016     // this is actually irrelevant since we only write out the path
00017     // component
00018     public $may_omit_host = true;
00019 
00020     public function doValidate(&$uri, $config, $context) {
00021         $result = explode(',', $uri->path, 2);
00022         $is_base64 = false;
00023         $charset = null;
00024         $content_type = null;
00025         if (count($result) == 2) {
00026             list($metadata, $data) = $result;
00027             // do some legwork on the metadata
00028             $metas = explode(';', $metadata);
00029             while(!empty($metas)) {
00030                 $cur = array_shift($metas);
00031                 if ($cur == 'base64') {
00032                     $is_base64 = true;
00033                     break;
00034                 }
00035                 if (substr($cur, 0, 8) == 'charset=') {
00036                     // doesn't match if there are arbitrary spaces, but
00037                     // whatever dude
00038                     if ($charset !== null) continue; // garbage
00039                     $charset = substr($cur, 8); // not used
00040                 } else {
00041                     if ($content_type !== null) continue; // garbage
00042                     $content_type = $cur;
00043                 }
00044             }
00045         } else {
00046             $data = $result[0];
00047         }
00048         if ($content_type !== null && empty($this->allowed_types[$content_type])) {
00049             return false;
00050         }
00051         if ($charset !== null) {
00052             // error; we don't allow plaintext stuff
00053             $charset = null;
00054         }
00055         $data = rawurldecode($data);
00056         if ($is_base64) {
00057             $raw_data = base64_decode($data);
00058         } else {
00059             $raw_data = $data;
00060         }
00061         // XXX probably want to refactor this into a general mechanism
00062         // for filtering arbitrary content types
00063         $file = tempnam("/tmp", "");
00064         file_put_contents($file, $raw_data);
00065         if (function_exists('exif_imagetype')) {
00066             $image_code = exif_imagetype($file);
00067         } elseif (function_exists('getimagesize')) {
00068             set_error_handler(array($this, 'muteErrorHandler'));
00069             $info = getimagesize($file);
00070             restore_error_handler();
00071             if ($info == false) return false;
00072             $image_code = $info[2];
00073         } else {
00074             trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR);
00075         }
00076         $real_content_type = image_type_to_mime_type($image_code);
00077         if ($real_content_type != $content_type) {
00078             // we're nice guys; if the content type is something else we
00079             // support, change it over
00080             if (empty($this->allowed_types[$real_content_type])) return false;
00081             $content_type = $real_content_type;
00082         }
00083         // ok, it's kosher, rewrite what we need
00084         $uri->userinfo = null;
00085         $uri->host = null;
00086         $uri->port = null;
00087         $uri->fragment = null;
00088         $uri->query = null;
00089         $uri->path = "$content_type;base64," . base64_encode($raw_data);
00090         return true;
00091     }
00092 
00093     public function muteErrorHandler($errno, $errstr) {}
00094 
00095 }
00096