Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * Validates the attributes of a token. Doesn't manage required attributes
5
 * very well. The only reason we factored this out was because RemoveForeignElements
6
 * also needed it besides ValidateAttributes.
7
 */
8
class HTMLPurifier_AttrValidator
9
{
10
 
11
    /**
12
     * Validates the attributes of a token, mutating it as necessary.
13
     * that has valid tokens
14
     * @param HTMLPurifier_Token $token Token to validate.
15
     * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config
16
     * @param HTMLPurifier_Context $context Instance of HTMLPurifier_Context
17
     */
18
    public function validateToken($token, $config, $context)
19
    {
20
        $definition = $config->getHTMLDefinition();
21
        $e =& $context->get('ErrorCollector', true);
22
 
23
        // initialize IDAccumulator if necessary
24
        $ok =& $context->get('IDAccumulator', true);
25
        if (!$ok) {
26
            $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
27
            $context->register('IDAccumulator', $id_accumulator);
28
        }
29
 
30
        // initialize CurrentToken if necessary
31
        $current_token =& $context->get('CurrentToken', true);
32
        if (!$current_token) {
33
            $context->register('CurrentToken', $token);
34
        }
35
 
36
        if (!$token instanceof HTMLPurifier_Token_Start &&
37
            !$token instanceof HTMLPurifier_Token_Empty
38
        ) {
39
            return;
40
        }
41
 
42
        // create alias to global definition array, see also $defs
43
        // DEFINITION CALL
44
        $d_defs = $definition->info_global_attr;
45
 
46
        // don't update token until the very end, to ensure an atomic update
47
        $attr = $token->attr;
48
 
49
        // do global transformations (pre)
50
        // nothing currently utilizes this
51
        foreach ($definition->info_attr_transform_pre as $transform) {
52
            $attr = $transform->transform($o = $attr, $config, $context);
53
            if ($e) {
54
                if ($attr != $o) {
55
                    $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
56
                }
57
            }
58
        }
59
 
60
        // do local transformations only applicable to this element (pre)
61
        // ex. <p align="right"> to <p style="text-align:right;">
62
        foreach ($definition->info[$token->name]->attr_transform_pre as $transform) {
63
            $attr = $transform->transform($o = $attr, $config, $context);
64
            if ($e) {
65
                if ($attr != $o) {
66
                    $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
67
                }
68
            }
69
        }
70
 
71
        // create alias to this element's attribute definition array, see
72
        // also $d_defs (global attribute definition array)
73
        // DEFINITION CALL
74
        $defs = $definition->info[$token->name]->attr;
75
 
76
        $attr_key = false;
77
        $context->register('CurrentAttr', $attr_key);
78
 
79
        // iterate through all the attribute keypairs
80
        // Watch out for name collisions: $key has previously been used
81
        foreach ($attr as $attr_key => $value) {
82
 
83
            // call the definition
84
            if (isset($defs[$attr_key])) {
85
                // there is a local definition defined
86
                if ($defs[$attr_key] === false) {
87
                    // We've explicitly been told not to allow this element.
88
                    // This is usually when there's a global definition
89
                    // that must be overridden.
90
                    // Theoretically speaking, we could have a
91
                    // AttrDef_DenyAll, but this is faster!
92
                    $result = false;
93
                } else {
94
                    // validate according to the element's definition
95
                    $result = $defs[$attr_key]->validate(
96
                        $value,
97
                        $config,
98
                        $context
99
                    );
100
                }
101
            } elseif (isset($d_defs[$attr_key])) {
102
                // there is a global definition defined, validate according
103
                // to the global definition
104
                $result = $d_defs[$attr_key]->validate(
105
                    $value,
106
                    $config,
107
                    $context
108
                );
109
            } else {
110
                // system never heard of the attribute? DELETE!
111
                $result = false;
112
            }
113
 
114
            // put the results into effect
115
            if ($result === false || $result === null) {
116
                // this is a generic error message that should replaced
117
                // with more specific ones when possible
118
                if ($e) {
119
                    $e->send(E_ERROR, 'AttrValidator: Attribute removed');
120
                }
121
 
122
                // remove the attribute
123
                unset($attr[$attr_key]);
124
            } elseif (is_string($result)) {
125
                // generally, if a substitution is happening, there
126
                // was some sort of implicit correction going on. We'll
127
                // delegate it to the attribute classes to say exactly what.
128
 
129
                // simple substitution
130
                $attr[$attr_key] = $result;
131
            } else {
132
                // nothing happens
133
            }
134
 
135
            // we'd also want slightly more complicated substitution
136
            // involving an array as the return value,
137
            // although we're not sure how colliding attributes would
138
            // resolve (certain ones would be completely overriden,
139
            // others would prepend themselves).
140
        }
141
 
142
        $context->destroy('CurrentAttr');
143
 
144
        // post transforms
145
 
146
        // global (error reporting untested)
147
        foreach ($definition->info_attr_transform_post as $transform) {
148
            $attr = $transform->transform($o = $attr, $config, $context);
149
            if ($e) {
150
                if ($attr != $o) {
151
                    $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
152
                }
153
            }
154
        }
155
 
156
        // local (error reporting untested)
157
        foreach ($definition->info[$token->name]->attr_transform_post as $transform) {
158
            $attr = $transform->transform($o = $attr, $config, $context);
159
            if ($e) {
160
                if ($attr != $o) {
161
                    $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
162
                }
163
            }
164
        }
165
 
166
        $token->attr = $attr;
167
 
168
        // destroy CurrentToken if we made it ourselves
169
        if (!$current_token) {
170
            $context->destroy('CurrentToken');
171
        }
172
 
173
    }
174
 
175
 
176
}
177
 
178
// vim: et sw=4 sts=4