~ubuntu-branches/ubuntu/natty/moodle/natty

« back to all changes in this revision

Viewing changes to lib/htmlpurifier/HTMLPurifier/CSSDefinition.php

  • Committer: Bazaar Package Importer
  • Author(s): Tomasz Muras
  • Date: 2010-10-30 12:19:28 UTC
  • mfrom: (1.1.12 upstream) (3.1.10 squeeze)
  • Revision ID: james.westby@ubuntu.com-20101030121928-qzobi6mctpnk4dif
Tags: 1.9.9.dfsg2-2
* Added Romanian translation
* Updated Japanese translation (closes: #596820)
* Backporting security fixes from Moodle 1.9.10 (closes: #601384)
   - Updated embedded CAS to 1.1.3
   - Added patch for MDL-24523:
     clean_text() not filtering text in markdown format
   - Added patch for MDL-24810 and upgraded customized HTML Purifier to 4.2.0 
   - Added patch for MDL-24258:
     students can delete their forum posts later than $CFG->maxeditingtime 
     under certain conditions
   - Added patch for MDL-23377:
     Can't delete quiz attempts in course without enrolled students

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
<?php
2
2
 
3
 
require_once 'HTMLPurifier/Definition.php';
4
 
 
5
 
require_once 'HTMLPurifier/AttrDef/CSS/Background.php';
6
 
require_once 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
7
 
require_once 'HTMLPurifier/AttrDef/CSS/Border.php';
8
 
require_once 'HTMLPurifier/AttrDef/CSS/Color.php';
9
 
require_once 'HTMLPurifier/AttrDef/CSS/Composite.php';
10
 
require_once 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
11
 
require_once 'HTMLPurifier/AttrDef/CSS/Font.php';
12
 
require_once 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
13
 
require_once 'HTMLPurifier/AttrDef/CSS/Length.php';
14
 
require_once 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
15
 
require_once 'HTMLPurifier/AttrDef/CSS/Multiple.php';
16
 
require_once 'HTMLPurifier/AttrDef/CSS/Percentage.php';
17
 
require_once 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
18
 
require_once 'HTMLPurifier/AttrDef/CSS/URI.php';
19
 
require_once 'HTMLPurifier/AttrDef/Enum.php';
20
 
require_once 'HTMLPurifier/AttrDef/Switch.php';
21
 
 
22
 
HTMLPurifier_ConfigSchema::define(
23
 
    'CSS', 'DefinitionRev', 1, 'int', '
24
 
<p>
25
 
    Revision identifier for your custom definition. See
26
 
    %HTML.DefinitionRev for details. This directive has been available
27
 
    since 2.0.0.
28
 
</p>
29
 
');
30
 
 
31
 
HTMLPurifier_ConfigSchema::define(
32
 
    'CSS', 'MaxImgLength', '1200px', 'string/null', '
33
 
<p>
34
 
 This parameter sets the maximum allowed length on <code>img</code> tags,
35
 
 effectively the <code>width</code> and <code>height</code> properties.
36
 
 Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is
37
 
 in place to prevent imagecrash attacks, disable with null at your own risk.
38
 
 This directive is similar to %HTML.MaxImgLength, and both should be
39
 
 concurrently edited, although there are
40
 
 subtle differences in the input format (the CSS max is a number with
41
 
 a unit).
42
 
</p>
43
 
');
44
 
 
45
3
/**
46
4
 * Defines allowed CSS attributes and what their values are.
47
5
 * @see HTMLPurifier_HTMLDefinition
48
6
 */
49
7
class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
50
8
{
51
 
    
52
 
    var $type = 'CSS';
53
 
    
 
9
 
 
10
    public $type = 'CSS';
 
11
 
54
12
    /**
55
13
     * Assoc array of attribute name to definition object.
56
14
     */
57
 
    var $info = array();
58
 
    
 
15
    public $info = array();
 
16
 
59
17
    /**
60
18
     * Constructs the info array.  The meat of this class.
61
19
     */
62
 
    function doSetup($config) {
63
 
        
 
20
    protected function doSetup($config) {
 
21
 
64
22
        $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
65
23
            array('left', 'right', 'center', 'justify'), false);
66
 
        
 
24
 
67
25
        $border_style =
68
 
        $this->info['border-bottom-style'] = 
69
 
        $this->info['border-right-style'] = 
70
 
        $this->info['border-left-style'] = 
 
26
        $this->info['border-bottom-style'] =
 
27
        $this->info['border-right-style'] =
 
28
        $this->info['border-left-style'] =
71
29
        $this->info['border-top-style'] =  new HTMLPurifier_AttrDef_Enum(
72
30
            array('none', 'hidden', 'dotted', 'dashed', 'solid', 'double',
73
31
            'groove', 'ridge', 'inset', 'outset'), false);
74
 
        
 
32
 
75
33
        $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style);
76
 
        
 
34
 
77
35
        $this->info['clear'] = new HTMLPurifier_AttrDef_Enum(
78
36
            array('none', 'left', 'right', 'both'), false);
79
37
        $this->info['float'] = new HTMLPurifier_AttrDef_Enum(
82
40
            array('normal', 'italic', 'oblique'), false);
83
41
        $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
84
42
            array('normal', 'small-caps'), false);
85
 
        
 
43
 
86
44
        $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
87
45
            array(
88
46
                new HTMLPurifier_AttrDef_Enum(array('none')),
89
47
                new HTMLPurifier_AttrDef_CSS_URI()
90
48
            )
91
49
        );
92
 
        
 
50
 
93
51
        $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
94
52
            array('inside', 'outside'), false);
95
53
        $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
96
54
            array('disc', 'circle', 'square', 'decimal', 'lower-roman',
97
55
            'upper-roman', 'lower-alpha', 'upper-alpha', 'none'), false);
98
56
        $this->info['list-style-image'] = $uri_or_none;
99
 
        
 
57
 
100
58
        $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config);
101
 
        
 
59
 
102
60
        $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum(
103
61
            array('capitalize', 'uppercase', 'lowercase', 'none'), false);
104
62
        $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color();
105
 
        
 
63
 
106
64
        $this->info['background-image'] = $uri_or_none;
107
65
        $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum(
108
66
            array('repeat', 'repeat-x', 'repeat-y', 'no-repeat')
111
69
            array('scroll', 'fixed')
112
70
        );
113
71
        $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
114
 
        
115
 
        $border_color = 
116
 
        $this->info['border-top-color'] = 
117
 
        $this->info['border-bottom-color'] = 
118
 
        $this->info['border-left-color'] = 
119
 
        $this->info['border-right-color'] = 
 
72
 
 
73
        $border_color =
 
74
        $this->info['border-top-color'] =
 
75
        $this->info['border-bottom-color'] =
 
76
        $this->info['border-left-color'] =
 
77
        $this->info['border-right-color'] =
120
78
        $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
121
79
            new HTMLPurifier_AttrDef_Enum(array('transparent')),
122
80
            new HTMLPurifier_AttrDef_CSS_Color()
123
81
        ));
124
 
        
 
82
 
125
83
        $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
126
 
        
 
84
 
127
85
        $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color);
128
 
        
129
 
        $border_width = 
130
 
        $this->info['border-top-width'] = 
131
 
        $this->info['border-bottom-width'] = 
132
 
        $this->info['border-left-width'] = 
 
86
 
 
87
        $border_width =
 
88
        $this->info['border-top-width'] =
 
89
        $this->info['border-bottom-width'] =
 
90
        $this->info['border-left-width'] =
133
91
        $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
134
92
            new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
135
93
            new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
136
94
        ));
137
 
        
 
95
 
138
96
        $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
139
 
        
 
97
 
140
98
        $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
141
99
            new HTMLPurifier_AttrDef_Enum(array('normal')),
142
100
            new HTMLPurifier_AttrDef_CSS_Length()
143
101
        ));
144
 
        
 
102
 
145
103
        $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
146
104
            new HTMLPurifier_AttrDef_Enum(array('normal')),
147
105
            new HTMLPurifier_AttrDef_CSS_Length()
148
106
        ));
149
 
        
 
107
 
150
108
        $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
151
109
            new HTMLPurifier_AttrDef_Enum(array('xx-small', 'x-small',
152
110
                'small', 'medium', 'large', 'x-large', 'xx-large',
154
112
            new HTMLPurifier_AttrDef_CSS_Percentage(),
155
113
            new HTMLPurifier_AttrDef_CSS_Length()
156
114
        ));
157
 
        
 
115
 
158
116
        $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
159
117
            new HTMLPurifier_AttrDef_Enum(array('normal')),
160
118
            new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
161
119
            new HTMLPurifier_AttrDef_CSS_Length('0'),
162
120
            new HTMLPurifier_AttrDef_CSS_Percentage(true)
163
121
        ));
164
 
        
 
122
 
165
123
        $margin =
166
 
        $this->info['margin-top'] = 
167
 
        $this->info['margin-bottom'] = 
168
 
        $this->info['margin-left'] = 
 
124
        $this->info['margin-top'] =
 
125
        $this->info['margin-bottom'] =
 
126
        $this->info['margin-left'] =
169
127
        $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
170
128
            new HTMLPurifier_AttrDef_CSS_Length(),
171
129
            new HTMLPurifier_AttrDef_CSS_Percentage(),
172
130
            new HTMLPurifier_AttrDef_Enum(array('auto'))
173
131
        ));
174
 
        
 
132
 
175
133
        $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
176
 
        
 
134
 
177
135
        // non-negative
178
136
        $padding =
179
 
        $this->info['padding-top'] = 
180
 
        $this->info['padding-bottom'] = 
181
 
        $this->info['padding-left'] = 
 
137
        $this->info['padding-top'] =
 
138
        $this->info['padding-bottom'] =
 
139
        $this->info['padding-left'] =
182
140
        $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
183
141
            new HTMLPurifier_AttrDef_CSS_Length('0'),
184
142
            new HTMLPurifier_AttrDef_CSS_Percentage(true)
185
143
        ));
186
 
        
 
144
 
187
145
        $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
188
 
        
 
146
 
189
147
        $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
190
148
            new HTMLPurifier_AttrDef_CSS_Length(),
191
149
            new HTMLPurifier_AttrDef_CSS_Percentage()
192
150
        ));
193
 
        
 
151
 
194
152
        $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array(
195
153
            new HTMLPurifier_AttrDef_CSS_Length('0'),
196
154
            new HTMLPurifier_AttrDef_CSS_Percentage(true),
197
155
            new HTMLPurifier_AttrDef_Enum(array('auto'))
198
156
        ));
199
 
        $max = $config->get('CSS', 'MaxImgLength');
 
157
        $max = $config->get('CSS.MaxImgLength');
 
158
 
200
159
        $this->info['width'] =
201
160
        $this->info['height'] =
202
161
            $max === null ?
203
 
            $trusted_wh : 
 
162
            $trusted_wh :
204
163
            new HTMLPurifier_AttrDef_Switch('img',
205
164
                // For img tags:
206
165
                new HTMLPurifier_AttrDef_CSS_Composite(array(
210
169
                // For everyone else:
211
170
                $trusted_wh
212
171
            );
213
 
        
 
172
 
214
173
        $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
215
 
        
 
174
 
216
175
        $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
217
 
        
 
176
 
218
177
        // this could use specialized code
219
178
        $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
220
179
            array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300',
221
180
            '400', '500', '600', '700', '800', '900'), false);
222
 
        
 
181
 
223
182
        // MUST be called after other font properties, as it references
224
183
        // a CSSDefinition object
225
184
        $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config);
226
 
        
 
185
 
227
186
        // same here
228
187
        $this->info['border'] =
229
 
        $this->info['border-bottom'] = 
230
 
        $this->info['border-top'] = 
231
 
        $this->info['border-left'] = 
 
188
        $this->info['border-bottom'] =
 
189
        $this->info['border-top'] =
 
190
        $this->info['border-left'] =
232
191
        $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
233
 
        
 
192
 
234
193
        $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(array(
235
194
            'collapse', 'separate'));
236
 
        
 
195
 
237
196
        $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(array(
238
197
            'top', 'bottom'));
239
 
        
 
198
 
240
199
        $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(array(
241
200
            'auto', 'fixed'));
242
 
        
 
201
 
243
202
        $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
244
203
            new HTMLPurifier_AttrDef_Enum(array('baseline', 'sub', 'super',
245
204
                'top', 'text-top', 'middle', 'bottom', 'text-bottom')),
246
205
            new HTMLPurifier_AttrDef_CSS_Length(),
247
206
            new HTMLPurifier_AttrDef_CSS_Percentage()
248
207
        ));
249
 
        
 
208
 
250
209
        $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
251
 
        
 
210
 
252
211
        // partial support
253
212
        $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap'));
254
 
        
255
 
    }
256
 
    
 
213
 
 
214
        if ($config->get('CSS.Proprietary')) {
 
215
            $this->doSetupProprietary($config);
 
216
        }
 
217
 
 
218
        if ($config->get('CSS.AllowTricky')) {
 
219
            $this->doSetupTricky($config);
 
220
        }
 
221
 
 
222
        $allow_important = $config->get('CSS.AllowImportant');
 
223
        // wrap all attr-defs with decorator that handles !important
 
224
        foreach ($this->info as $k => $v) {
 
225
            $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
 
226
        }
 
227
 
 
228
        $this->setupConfigStuff($config);
 
229
    }
 
230
 
 
231
    protected function doSetupProprietary($config) {
 
232
        // Internet Explorer only scrollbar colors
 
233
        $this->info['scrollbar-arrow-color']        = new HTMLPurifier_AttrDef_CSS_Color();
 
234
        $this->info['scrollbar-base-color']         = new HTMLPurifier_AttrDef_CSS_Color();
 
235
        $this->info['scrollbar-darkshadow-color']   = new HTMLPurifier_AttrDef_CSS_Color();
 
236
        $this->info['scrollbar-face-color']         = new HTMLPurifier_AttrDef_CSS_Color();
 
237
        $this->info['scrollbar-highlight-color']    = new HTMLPurifier_AttrDef_CSS_Color();
 
238
        $this->info['scrollbar-shadow-color']       = new HTMLPurifier_AttrDef_CSS_Color();
 
239
 
 
240
        // technically not proprietary, but CSS3, and no one supports it
 
241
        $this->info['opacity']          = new HTMLPurifier_AttrDef_CSS_AlphaValue();
 
242
        $this->info['-moz-opacity']     = new HTMLPurifier_AttrDef_CSS_AlphaValue();
 
243
        $this->info['-khtml-opacity']   = new HTMLPurifier_AttrDef_CSS_AlphaValue();
 
244
 
 
245
        // only opacity, for now
 
246
        $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
 
247
 
 
248
    }
 
249
 
 
250
    protected function doSetupTricky($config) {
 
251
        $this->info['display'] = new HTMLPurifier_AttrDef_Enum(array(
 
252
            'inline', 'block', 'list-item', 'run-in', 'compact',
 
253
            'marker', 'table', 'inline-table', 'table-row-group',
 
254
            'table-header-group', 'table-footer-group', 'table-row',
 
255
            'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none'
 
256
        ));
 
257
        $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(array(
 
258
            'visible', 'hidden', 'collapse'
 
259
        ));
 
260
        $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
 
261
    }
 
262
 
 
263
 
 
264
    /**
 
265
     * Performs extra config-based processing. Based off of
 
266
     * HTMLPurifier_HTMLDefinition.
 
267
     * @todo Refactor duplicate elements into common class (probably using
 
268
     *       composition, not inheritance).
 
269
     */
 
270
    protected function setupConfigStuff($config) {
 
271
 
 
272
        // setup allowed elements
 
273
        $support = "(for information on implementing this, see the ".
 
274
                   "support forums) ";
 
275
        $allowed_properties = $config->get('CSS.AllowedProperties');
 
276
        if ($allowed_properties !== null) {
 
277
            foreach ($this->info as $name => $d) {
 
278
                if(!isset($allowed_properties[$name])) unset($this->info[$name]);
 
279
                unset($allowed_properties[$name]);
 
280
            }
 
281
            // emit errors
 
282
            foreach ($allowed_properties as $name => $d) {
 
283
                // :TODO: Is this htmlspecialchars() call really necessary?
 
284
                $name = htmlspecialchars($name);
 
285
                trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
 
286
            }
 
287
        }
 
288
 
 
289
        $forbidden_properties = $config->get('CSS.ForbiddenProperties');
 
290
        if ($forbidden_properties !== null) {
 
291
            foreach ($this->info as $name => $d) {
 
292
                if (isset($forbidden_properties[$name])) {
 
293
                    unset($this->info[$name]);
 
294
                }
 
295
            }
 
296
        }
 
297
 
 
298
    }
257
299
}
258
300
 
 
301
// vim: et sw=4 sts=4