Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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