diff --git a/library/HTMLPurifier/VarParser.php b/library/HTMLPurifier/VarParser.php
index 1d07329a..bb0313f1 100644
--- a/library/HTMLPurifier/VarParser.php
+++ b/library/HTMLPurifier/VarParser.php
@@ -2,9 +2,9 @@
/**
* Parses string representations into their corresponding native PHP
- * variable type.
+ * variable type. The base implementation does a simple type-check.
*/
-abstract class HTMLPurifier_VarParser
+class HTMLPurifier_VarParser
{
/**
@@ -34,6 +34,81 @@ abstract class HTMLPurifier_VarParser
* @param $allow_null Whether or not to permit null as a value
* @return Validated and type-coerced variable
*/
- abstract public function parse($var, $type, $allow_null = false);
+ final public function parse($var, $type, $allow_null = false) {
+ if (!isset(HTMLPurifier_VarParser::$types[$type])) {
+ throw new HTMLPurifier_VarParserException("Invalid type $type");
+ }
+ $var = $this->parseImplementation($var, $type, $allow_null);
+ if ($allow_null && $var === null) return null;
+ // These are basic checks, to make sure nothing horribly wrong
+ // happened in our implementations.
+ switch ($type) {
+ case 'string':
+ case 'istring':
+ case 'text':
+ case 'itext':
+ if (!is_string($var)) break;
+ if ($type[0] == 'i') $var = strtolower($var);
+ return $var;
+ case 'int':
+ if (!is_int($var)) break;
+ return $var;
+ case 'float':
+ if (!is_float($var)) break;
+ return $var;
+ case 'bool':
+ if (!is_bool($var)) break;
+ return $var;
+ case 'lookup':
+ case 'list':
+ case 'hash':
+ if (!is_array($var)) break;
+ if ($type === 'lookup') {
+ foreach ($var as $k) if ($k !== true) $this->error('Lookup table contains value other than true');
+ } elseif ($type === 'list') {
+ $keys = array_keys($var);
+ if (array_keys($keys) !== $keys) $this->error('Indices for list are not uniform');
+ }
+ return $var;
+ case 'mixed':
+ return $var;
+ default:
+ $this->errorInconsistent(__CLASS__, $type);
+ }
+ $this->errorGeneric($var, $type);
+ }
+
+ /**
+ * Actually implements the parsing. Base implementation is to not
+ * do anything to $var. Subclasses should overload this!
+ */
+ protected function parseImplementation($var, $type, $allow_null) {
+ return $var;
+ }
+
+ /**
+ * Throws an exception.
+ */
+ protected function error($msg) {
+ throw new HTMLPurifier_VarParserException($msg);
+ }
+
+ /**
+ * Throws an inconsistency exception.
+ * @note This should not ever be called. It would be called if we
+ * extend the allowed values of HTMLPurifier_VarParser without
+ * updating subclasses.
+ */
+ protected function errorInconsistent($class, $type) {
+ throw new HTMLPurifier_Exception("Inconsistency in $class: $type not implemented");
+ }
+
+ /**
+ * Generic error for if a type didn't work.
+ */
+ protected function errorGeneric($var, $type) {
+ $vtype = gettype($var);
+ $this->error("Expected type $type, got $vtype");
+ }
}
diff --git a/library/HTMLPurifier/VarParser/Flexible.php b/library/HTMLPurifier/VarParser/Flexible.php
index fcec974b..1c5ddcb7 100644
--- a/library/HTMLPurifier/VarParser/Flexible.php
+++ b/library/HTMLPurifier/VarParser/Flexible.php
@@ -8,31 +8,23 @@
class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
{
- public function parse($var, $type, $allow_null = false) {
- if (!isset(HTMLPurifier_VarParser::$types[$type])) {
- throw new HTMLPurifier_VarParserException("Invalid type $type");
- }
+ protected function parseImplementation($var, $type, $allow_null) {
if ($allow_null && $var === null) return null;
switch ($type) {
// Note: if code "breaks" from the switch, it triggers a generic
// exception to be thrown. Specific errors can be specifically
// done here.
case 'mixed':
- return $var;
case 'istring':
case 'string':
- case 'text': // no difference, just is longer/multiple line string
+ case 'text':
case 'itext':
- if (!is_string($var)) break;
- if ($type === 'istring' || $type === 'itext') $var = strtolower($var);
return $var;
case 'int':
if (is_string($var) && ctype_digit($var)) $var = (int) $var;
- elseif (!is_int($var)) break;
return $var;
case 'float':
if (is_string($var) && is_numeric($var)) $var = (float) $var;
- elseif (!is_float($var)) break;
return $var;
case 'bool':
if (is_int($var) && ($var === 0 || $var === 1)) {
@@ -45,7 +37,7 @@ class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
} else {
throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type");
}
- } elseif (!is_bool($var)) break;
+ }
return $var;
case 'list':
case 'hash':
@@ -94,10 +86,9 @@ class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
}
return $var;
default:
- // This should not happen!
- throw new HTMLPurifier_Exception("Inconsistency in HTMLPurifier_VarParser_Flexible: $type is not implemented");
+ $this->errorInconsistent(__CLASS__, $type);
}
- throw new HTMLPurifier_VarParserException("Invalid input for type $type");
+ $this->errorGeneric($var, $type);
}
}