--- /dev/null
+<?php\r
+\r
+/**\r
+ * Performs safe variable parsing based on types which can be used by\r
+ * users. This may not be able to represent all possible data inputs,\r
+ * however.\r
+ */\r
+class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser\r
+{\r
+ /**\r
+ * @param mixed $var\r
+ * @param int $type\r
+ * @param bool $allow_null\r
+ * @return array|bool|float|int|mixed|null|string\r
+ * @throws HTMLPurifier_VarParserException\r
+ */\r
+ protected function parseImplementation($var, $type, $allow_null)\r
+ {\r
+ if ($allow_null && $var === null) {\r
+ return null;\r
+ }\r
+ switch ($type) {\r
+ // Note: if code "breaks" from the switch, it triggers a generic\r
+ // exception to be thrown. Specific errors can be specifically\r
+ // done here.\r
+ case self::MIXED:\r
+ case self::ISTRING:\r
+ case self::STRING:\r
+ case self::TEXT:\r
+ case self::ITEXT:\r
+ return $var;\r
+ case self::INT:\r
+ if (is_string($var) && ctype_digit($var)) {\r
+ $var = (int)$var;\r
+ }\r
+ return $var;\r
+ case self::FLOAT:\r
+ if ((is_string($var) && is_numeric($var)) || is_int($var)) {\r
+ $var = (float)$var;\r
+ }\r
+ return $var;\r
+ case self::BOOL:\r
+ if (is_int($var) && ($var === 0 || $var === 1)) {\r
+ $var = (bool)$var;\r
+ } elseif (is_string($var)) {\r
+ if ($var == 'on' || $var == 'true' || $var == '1') {\r
+ $var = true;\r
+ } elseif ($var == 'off' || $var == 'false' || $var == '0') {\r
+ $var = false;\r
+ } else {\r
+ throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type");\r
+ }\r
+ }\r
+ return $var;\r
+ case self::ALIST:\r
+ case self::HASH:\r
+ case self::LOOKUP:\r
+ if (is_string($var)) {\r
+ // special case: technically, this is an array with\r
+ // a single empty string item, but having an empty\r
+ // array is more intuitive\r
+ if ($var == '') {\r
+ return array();\r
+ }\r
+ if (strpos($var, "\n") === false && strpos($var, "\r") === false) {\r
+ // simplistic string to array method that only works\r
+ // for simple lists of tag names or alphanumeric characters\r
+ $var = explode(',', $var);\r
+ } else {\r
+ $var = preg_split('/(,|[\n\r]+)/', $var);\r
+ }\r
+ // remove spaces\r
+ foreach ($var as $i => $j) {\r
+ $var[$i] = trim($j);\r
+ }\r
+ if ($type === self::HASH) {\r
+ // key:value,key2:value2\r
+ $nvar = array();\r
+ foreach ($var as $keypair) {\r
+ $c = explode(':', $keypair, 2);\r
+ if (!isset($c[1])) {\r
+ continue;\r
+ }\r
+ $nvar[trim($c[0])] = trim($c[1]);\r
+ }\r
+ $var = $nvar;\r
+ }\r
+ }\r
+ if (!is_array($var)) {\r
+ break;\r
+ }\r
+ $keys = array_keys($var);\r
+ if ($keys === array_keys($keys)) {\r
+ if ($type == self::ALIST) {\r
+ return $var;\r
+ } elseif ($type == self::LOOKUP) {\r
+ $new = array();\r
+ foreach ($var as $key) {\r
+ $new[$key] = true;\r
+ }\r
+ return $new;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ if ($type === self::ALIST) {\r
+ trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING);\r
+ return array_values($var);\r
+ }\r
+ if ($type === self::LOOKUP) {\r
+ foreach ($var as $key => $value) {\r
+ if ($value !== true) {\r
+ trigger_error(\r
+ "Lookup array has non-true value at key '$key'; " .\r
+ "maybe your input array was not indexed numerically",\r
+ E_USER_WARNING\r
+ );\r
+ }\r
+ $var[$key] = true;\r
+ }\r
+ }\r
+ return $var;\r
+ default:\r
+ $this->errorInconsistent(__CLASS__, $type);\r
+ }\r
+ $this->errorGeneric($var, $type);\r
+ }\r
+}\r
+\r
+// vim: et sw=4 sts=4\r