1 <?php 2 3 /** 4 * Parses string representations into their corresponding native PHP 5 * variable type. The base implementation does a simple type-check. 6 */ 7 class HTMLPurifier_VarParser 8 { 9 10 const C_STRING = 1; 11 const ISTRING = 2; 12 const TEXT = 3; 13 const ITEXT = 4; 14 const C_INT = 5; 15 const C_FLOAT = 6; 16 const C_BOOL = 7; 17 const LOOKUP = 8; 18 const ALIST = 9; 19 const HASH = 10; 20 const C_MIXED = 11; 21 22 /** 23 * Lookup table of allowed types. Mainly for backwards compatibility, but 24 * also convenient for transforming string type names to the integer constants. 25 */ 26 public static $types = array( 27 'string' => self::C_STRING, 28 'istring' => self::ISTRING, 29 'text' => self::TEXT, 30 'itext' => self::ITEXT, 31 'int' => self::C_INT, 32 'float' => self::C_FLOAT, 33 'bool' => self::C_BOOL, 34 'lookup' => self::LOOKUP, 35 'list' => self::ALIST, 36 'hash' => self::HASH, 37 'mixed' => self::C_MIXED 38 ); 39 40 /** 41 * Lookup table of types that are string, and can have aliases or 42 * allowed value lists. 43 */ 44 public static $stringTypes = array( 45 self::C_STRING => true, 46 self::ISTRING => true, 47 self::TEXT => true, 48 self::ITEXT => true, 49 ); 50 51 /** 52 * Validate a variable according to type. 53 * It may return NULL as a valid type if $allow_null is true. 54 * 55 * @param mixed $var Variable to validate 56 * @param int $type Type of variable, see HTMLPurifier_VarParser->types 57 * @param bool $allow_null Whether or not to permit null as a value 58 * @return string Validated and type-coerced variable 59 * @throws HTMLPurifier_VarParserException 60 */ 61 final public function parse($var, $type, $allow_null = false) 62 { 63 if (is_string($type)) { 64 if (!isset(HTMLPurifier_VarParser::$types[$type])) { 65 throw new HTMLPurifier_VarParserException("Invalid type '$type'"); 66 } else { 67 $type = HTMLPurifier_VarParser::$types[$type]; 68 } 69 } 70 $var = $this->parseImplementation($var, $type, $allow_null); 71 if ($allow_null && $var === null) { 72 return null; 73 } 74 // These are basic checks, to make sure nothing horribly wrong 75 // happened in our implementations. 76 switch ($type) { 77 case (self::C_STRING): 78 case (self::ISTRING): 79 case (self::TEXT): 80 case (self::ITEXT): 81 if (!is_string($var)) { 82 break; 83 } 84 if ($type == self::ISTRING || $type == self::ITEXT) { 85 $var = strtolower($var); 86 } 87 return $var; 88 case (self::C_INT): 89 if (!is_int($var)) { 90 break; 91 } 92 return $var; 93 case (self::C_FLOAT): 94 if (!is_float($var)) { 95 break; 96 } 97 return $var; 98 case (self::C_BOOL): 99 if (!is_bool($var)) { 100 break; 101 } 102 return $var; 103 case (self::LOOKUP): 104 case (self::ALIST): 105 case (self::HASH): 106 if (!is_array($var)) { 107 break; 108 } 109 if ($type === self::LOOKUP) { 110 foreach ($var as $k) { 111 if ($k !== true) { 112 $this->error('Lookup table contains value other than true'); 113 } 114 } 115 } elseif ($type === self::ALIST) { 116 $keys = array_keys($var); 117 if (array_keys($keys) !== $keys) { 118 $this->error('Indices for list are not uniform'); 119 } 120 } 121 return $var; 122 case (self::C_MIXED): 123 return $var; 124 default: 125 $this->errorInconsistent(get_class($this), $type); 126 } 127 $this->errorGeneric($var, $type); 128 } 129 130 /** 131 * Actually implements the parsing. Base implementation does not 132 * do anything to $var. Subclasses should overload this! 133 * @param mixed $var 134 * @param int $type 135 * @param bool $allow_null 136 * @return string 137 */ 138 protected function parseImplementation($var, $type, $allow_null) 139 { 140 return $var; 141 } 142 143 /** 144 * Throws an exception. 145 * @throws HTMLPurifier_VarParserException 146 */ 147 protected function error($msg) 148 { 149 throw new HTMLPurifier_VarParserException($msg); 150 } 151 152 /** 153 * Throws an inconsistency exception. 154 * @note This should not ever be called. It would be called if we 155 * extend the allowed values of HTMLPurifier_VarParser without 156 * updating subclasses. 157 * @param string $class 158 * @param int $type 159 * @throws HTMLPurifier_Exception 160 */ 161 protected function errorInconsistent($class, $type) 162 { 163 throw new HTMLPurifier_Exception( 164 "Inconsistency in $class: " . HTMLPurifier_VarParser::getTypeName($type) . 165 " not implemented" 166 ); 167 } 168 169 /** 170 * Generic error for if a type didn't work. 171 * @param mixed $var 172 * @param int $type 173 */ 174 protected function errorGeneric($var, $type) 175 { 176 $vtype = gettype($var); 177 $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got $vtype"); 178 } 179 180 /** 181 * @param int $type 182 * @return string 183 */ 184 public static function getTypeName($type) 185 { 186 static $lookup; 187 if (!$lookup) { 188 // Lazy load the alternative lookup table 189 $lookup = array_flip(HTMLPurifier_VarParser::$types); 190 } 191 if (!isset($lookup[$type])) { 192 return 'unknown'; 193 } 194 return $lookup[$type]; 195 } 196 } 197 198 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body