]>
Commit | Line | Data |
---|---|---|
d4949327 NL |
1 | <?php\r |
2 | \r | |
3 | /**\r | |
4 | * Implements data: URI for base64 encoded images supported by GD.\r | |
5 | */\r | |
6 | class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme\r | |
7 | {\r | |
8 | /**\r | |
9 | * @type bool\r | |
10 | */\r | |
11 | public $browsable = true;\r | |
12 | \r | |
13 | /**\r | |
14 | * @type array\r | |
15 | */\r | |
16 | public $allowed_types = array(\r | |
17 | // you better write validation code for other types if you\r | |
18 | // decide to allow them\r | |
19 | 'image/jpeg' => true,\r | |
20 | 'image/gif' => true,\r | |
21 | 'image/png' => true,\r | |
22 | );\r | |
23 | // this is actually irrelevant since we only write out the path\r | |
24 | // component\r | |
25 | /**\r | |
26 | * @type bool\r | |
27 | */\r | |
28 | public $may_omit_host = true;\r | |
29 | \r | |
30 | /**\r | |
31 | * @param HTMLPurifier_URI $uri\r | |
32 | * @param HTMLPurifier_Config $config\r | |
33 | * @param HTMLPurifier_Context $context\r | |
34 | * @return bool\r | |
35 | */\r | |
36 | public function doValidate(&$uri, $config, $context)\r | |
37 | {\r | |
38 | $result = explode(',', $uri->path, 2);\r | |
39 | $is_base64 = false;\r | |
40 | $charset = null;\r | |
41 | $content_type = null;\r | |
42 | if (count($result) == 2) {\r | |
43 | list($metadata, $data) = $result;\r | |
44 | // do some legwork on the metadata\r | |
45 | $metas = explode(';', $metadata);\r | |
46 | while (!empty($metas)) {\r | |
47 | $cur = array_shift($metas);\r | |
48 | if ($cur == 'base64') {\r | |
49 | $is_base64 = true;\r | |
50 | break;\r | |
51 | }\r | |
52 | if (substr($cur, 0, 8) == 'charset=') {\r | |
53 | // doesn't match if there are arbitrary spaces, but\r | |
54 | // whatever dude\r | |
55 | if ($charset !== null) {\r | |
56 | continue;\r | |
57 | } // garbage\r | |
58 | $charset = substr($cur, 8); // not used\r | |
59 | } else {\r | |
60 | if ($content_type !== null) {\r | |
61 | continue;\r | |
62 | } // garbage\r | |
63 | $content_type = $cur;\r | |
64 | }\r | |
65 | }\r | |
66 | } else {\r | |
67 | $data = $result[0];\r | |
68 | }\r | |
69 | if ($content_type !== null && empty($this->allowed_types[$content_type])) {\r | |
70 | return false;\r | |
71 | }\r | |
72 | if ($charset !== null) {\r | |
73 | // error; we don't allow plaintext stuff\r | |
74 | $charset = null;\r | |
75 | }\r | |
76 | $data = rawurldecode($data);\r | |
77 | if ($is_base64) {\r | |
78 | $raw_data = base64_decode($data);\r | |
79 | } else {\r | |
80 | $raw_data = $data;\r | |
81 | }\r | |
82 | // XXX probably want to refactor this into a general mechanism\r | |
83 | // for filtering arbitrary content types\r | |
84 | $file = tempnam("/tmp", "");\r | |
85 | file_put_contents($file, $raw_data);\r | |
86 | if (function_exists('exif_imagetype')) {\r | |
87 | $image_code = exif_imagetype($file);\r | |
88 | unlink($file);\r | |
89 | } elseif (function_exists('getimagesize')) {\r | |
90 | set_error_handler(array($this, 'muteErrorHandler'));\r | |
91 | $info = getimagesize($file);\r | |
92 | restore_error_handler();\r | |
93 | unlink($file);\r | |
94 | if ($info == false) {\r | |
95 | return false;\r | |
96 | }\r | |
97 | $image_code = $info[2];\r | |
98 | } else {\r | |
99 | trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR);\r | |
100 | }\r | |
101 | $real_content_type = image_type_to_mime_type($image_code);\r | |
102 | if ($real_content_type != $content_type) {\r | |
103 | // we're nice guys; if the content type is something else we\r | |
104 | // support, change it over\r | |
105 | if (empty($this->allowed_types[$real_content_type])) {\r | |
106 | return false;\r | |
107 | }\r | |
108 | $content_type = $real_content_type;\r | |
109 | }\r | |
110 | // ok, it's kosher, rewrite what we need\r | |
111 | $uri->userinfo = null;\r | |
112 | $uri->host = null;\r | |
113 | $uri->port = null;\r | |
114 | $uri->fragment = null;\r | |
115 | $uri->query = null;\r | |
116 | $uri->path = "$content_type;base64," . base64_encode($raw_data);\r | |
117 | return true;\r | |
118 | }\r | |
119 | \r | |
120 | /**\r | |
121 | * @param int $errno\r | |
122 | * @param string $errstr\r | |
123 | */\r | |
124 | public function muteErrorHandler($errno, $errstr)\r | |
125 | {\r | |
126 | }\r | |
127 | }\r |