@@ -6,22 +6,22 @@ discard block |
||
6 | 6 | class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef |
7 | 7 | { |
8 | 8 | |
9 | - protected $mask = null; |
|
10 | - |
|
11 | - public function __construct() { |
|
12 | - $this->mask = '- '; |
|
13 | - for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c; |
|
14 | - for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c; |
|
15 | - for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine |
|
16 | - // special bytes used by UTF-8 |
|
17 | - for ($i = 0x80; $i <= 0xFF; $i++) { |
|
18 | - // We don't bother excluding invalid bytes in this range, |
|
19 | - // because the our restriction of well-formed UTF-8 will |
|
20 | - // prevent these from ever occurring. |
|
21 | - $this->mask .= chr($i); |
|
22 | - } |
|
23 | - |
|
24 | - /* |
|
9 | + protected $mask = null; |
|
10 | + |
|
11 | + public function __construct() { |
|
12 | + $this->mask = '- '; |
|
13 | + for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c; |
|
14 | + for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c; |
|
15 | + for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine |
|
16 | + // special bytes used by UTF-8 |
|
17 | + for ($i = 0x80; $i <= 0xFF; $i++) { |
|
18 | + // We don't bother excluding invalid bytes in this range, |
|
19 | + // because the our restriction of well-formed UTF-8 will |
|
20 | + // prevent these from ever occurring. |
|
21 | + $this->mask .= chr($i); |
|
22 | + } |
|
23 | + |
|
24 | + /* |
|
25 | 25 | PHP's internal strcspn implementation is |
26 | 26 | O(length of string * length of mask), making it inefficient |
27 | 27 | for large masks. However, it's still faster than |
@@ -36,161 +36,161 @@ discard block |
||
36 | 36 | c = *++p; |
37 | 37 | } |
38 | 38 | */ |
39 | - // possible optimization: invert the mask. |
|
40 | - } |
|
41 | - |
|
42 | - public function validate($string, $config, $context) { |
|
43 | - static $generic_names = array( |
|
44 | - 'serif' => true, |
|
45 | - 'sans-serif' => true, |
|
46 | - 'monospace' => true, |
|
47 | - 'fantasy' => true, |
|
48 | - 'cursive' => true |
|
49 | - ); |
|
50 | - $allowed_fonts = $config->get('CSS.AllowedFonts'); |
|
51 | - |
|
52 | - // assume that no font names contain commas in them |
|
53 | - $fonts = explode(',', $string); |
|
54 | - $final = ''; |
|
55 | - foreach($fonts as $font) { |
|
56 | - $font = trim($font); |
|
57 | - if ($font === '') continue; |
|
58 | - // match a generic name |
|
59 | - if (isset($generic_names[$font])) { |
|
60 | - if ($allowed_fonts === null || isset($allowed_fonts[$font])) { |
|
61 | - $final .= $font . ', '; |
|
62 | - } |
|
63 | - continue; |
|
64 | - } |
|
65 | - // match a quoted name |
|
66 | - if ($font[0] === '"' || $font[0] === "'") { |
|
67 | - $length = strlen($font); |
|
68 | - if ($length <= 2) continue; |
|
69 | - $quote = $font[0]; |
|
70 | - if ($font[$length - 1] !== $quote) continue; |
|
71 | - $font = substr($font, 1, $length - 2); |
|
72 | - } |
|
73 | - |
|
74 | - $font = $this->expandCSSEscape($font); |
|
75 | - |
|
76 | - // $font is a pure representation of the font name |
|
77 | - |
|
78 | - if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) { |
|
79 | - continue; |
|
80 | - } |
|
81 | - |
|
82 | - if (ctype_alnum($font) && $font !== '') { |
|
83 | - // very simple font, allow it in unharmed |
|
84 | - $final .= $font . ', '; |
|
85 | - continue; |
|
86 | - } |
|
87 | - |
|
88 | - // bugger out on whitespace. form feed (0C) really |
|
89 | - // shouldn't show up regardless |
|
90 | - $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font); |
|
91 | - |
|
92 | - // Here, there are various classes of characters which need |
|
93 | - // to be treated differently: |
|
94 | - // - Alphanumeric characters are essentially safe. We |
|
95 | - // handled these above. |
|
96 | - // - Spaces require quoting, though most parsers will do |
|
97 | - // the right thing if there aren't any characters that |
|
98 | - // can be misinterpreted |
|
99 | - // - Dashes rarely occur, but they fairly unproblematic |
|
100 | - // for parsing/rendering purposes. |
|
101 | - // The above characters cover the majority of Western font |
|
102 | - // names. |
|
103 | - // - Arbitrary Unicode characters not in ASCII. Because |
|
104 | - // most parsers give little thought to Unicode, treatment |
|
105 | - // of these codepoints is basically uniform, even for |
|
106 | - // punctuation-like codepoints. These characters can |
|
107 | - // show up in non-Western pages and are supported by most |
|
108 | - // major browsers, for example: "MS 明朝" is a |
|
109 | - // legitimate font-name |
|
110 | - // <http://ja.wikipedia.org/wiki/MS_明朝>. See |
|
111 | - // the CSS3 spec for more examples: |
|
112 | - // <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png> |
|
113 | - // You can see live samples of these on the Internet: |
|
114 | - // <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック> |
|
115 | - // However, most of these fonts have ASCII equivalents: |
|
116 | - // for example, 'MS Mincho', and it's considered |
|
117 | - // professional to use ASCII font names instead of |
|
118 | - // Unicode font names. Thanks Takeshi Terada for |
|
119 | - // providing this information. |
|
120 | - // The following characters, to my knowledge, have not been |
|
121 | - // used to name font names. |
|
122 | - // - Single quote. While theoretically you might find a |
|
123 | - // font name that has a single quote in its name (serving |
|
124 | - // as an apostrophe, e.g. Dave's Scribble), I haven't |
|
125 | - // been able to find any actual examples of this. |
|
126 | - // Internet Explorer's cssText translation (which I |
|
127 | - // believe is invoked by innerHTML) normalizes any |
|
128 | - // quoting to single quotes, and fails to escape single |
|
129 | - // quotes. (Note that this is not IE's behavior for all |
|
130 | - // CSS properties, just some sort of special casing for |
|
131 | - // font-family). So a single quote *cannot* be used |
|
132 | - // safely in the font-family context if there will be an |
|
133 | - // innerHTML/cssText translation. Note that Firefox 3.x |
|
134 | - // does this too. |
|
135 | - // - Double quote. In IE, these get normalized to |
|
136 | - // single-quotes, no matter what the encoding. (Fun |
|
137 | - // fact, in IE8, the 'content' CSS property gained |
|
138 | - // support, where they special cased to preserve encoded |
|
139 | - // double quotes, but still translate unadorned double |
|
140 | - // quotes into single quotes.) So, because their |
|
141 | - // fixpoint behavior is identical to single quotes, they |
|
142 | - // cannot be allowed either. Firefox 3.x displays |
|
143 | - // single-quote style behavior. |
|
144 | - // - Backslashes are reduced by one (so \\ -> \) every |
|
145 | - // iteration, so they cannot be used safely. This shows |
|
146 | - // up in IE7, IE8 and FF3 |
|
147 | - // - Semicolons, commas and backticks are handled properly. |
|
148 | - // - The rest of the ASCII punctuation is handled properly. |
|
149 | - // We haven't checked what browsers do to unadorned |
|
150 | - // versions, but this is not important as long as the |
|
151 | - // browser doesn't /remove/ surrounding quotes (as IE does |
|
152 | - // for HTML). |
|
153 | - // |
|
154 | - // With these results in hand, we conclude that there are |
|
155 | - // various levels of safety: |
|
156 | - // - Paranoid: alphanumeric, spaces and dashes(?) |
|
157 | - // - International: Paranoid + non-ASCII Unicode |
|
158 | - // - Edgy: Everything except quotes, backslashes |
|
159 | - // - NoJS: Standards compliance, e.g. sod IE. Note that |
|
160 | - // with some judicious character escaping (since certain |
|
161 | - // types of escaping doesn't work) this is theoretically |
|
162 | - // OK as long as innerHTML/cssText is not called. |
|
163 | - // We believe that international is a reasonable default |
|
164 | - // (that we will implement now), and once we do more |
|
165 | - // extensive research, we may feel comfortable with dropping |
|
166 | - // it down to edgy. |
|
167 | - |
|
168 | - // Edgy: alphanumeric, spaces, dashes and Unicode. Use of |
|
169 | - // str(c)spn assumes that the string was already well formed |
|
170 | - // Unicode (which of course it is). |
|
171 | - if (strspn($font, $this->mask) !== strlen($font)) { |
|
172 | - continue; |
|
173 | - } |
|
174 | - |
|
175 | - // Historical: |
|
176 | - // In the absence of innerHTML/cssText, these ugly |
|
177 | - // transforms don't pose a security risk (as \\ and \" |
|
178 | - // might--these escapes are not supported by most browsers). |
|
179 | - // We could try to be clever and use single-quote wrapping |
|
180 | - // when there is a double quote present, but I have choosen |
|
181 | - // not to implement that. (NOTE: you can reduce the amount |
|
182 | - // of escapes by one depending on what quoting style you use) |
|
183 | - // $font = str_replace('\\', '\\5C ', $font); |
|
184 | - // $font = str_replace('"', '\\22 ', $font); |
|
185 | - // $font = str_replace("'", '\\27 ', $font); |
|
186 | - |
|
187 | - // font possibly with spaces, requires quoting |
|
188 | - $final .= "'$font', "; |
|
189 | - } |
|
190 | - $final = rtrim($final, ', '); |
|
191 | - if ($final === '') return false; |
|
192 | - return $final; |
|
193 | - } |
|
39 | + // possible optimization: invert the mask. |
|
40 | + } |
|
41 | + |
|
42 | + public function validate($string, $config, $context) { |
|
43 | + static $generic_names = array( |
|
44 | + 'serif' => true, |
|
45 | + 'sans-serif' => true, |
|
46 | + 'monospace' => true, |
|
47 | + 'fantasy' => true, |
|
48 | + 'cursive' => true |
|
49 | + ); |
|
50 | + $allowed_fonts = $config->get('CSS.AllowedFonts'); |
|
51 | + |
|
52 | + // assume that no font names contain commas in them |
|
53 | + $fonts = explode(',', $string); |
|
54 | + $final = ''; |
|
55 | + foreach($fonts as $font) { |
|
56 | + $font = trim($font); |
|
57 | + if ($font === '') continue; |
|
58 | + // match a generic name |
|
59 | + if (isset($generic_names[$font])) { |
|
60 | + if ($allowed_fonts === null || isset($allowed_fonts[$font])) { |
|
61 | + $final .= $font . ', '; |
|
62 | + } |
|
63 | + continue; |
|
64 | + } |
|
65 | + // match a quoted name |
|
66 | + if ($font[0] === '"' || $font[0] === "'") { |
|
67 | + $length = strlen($font); |
|
68 | + if ($length <= 2) continue; |
|
69 | + $quote = $font[0]; |
|
70 | + if ($font[$length - 1] !== $quote) continue; |
|
71 | + $font = substr($font, 1, $length - 2); |
|
72 | + } |
|
73 | + |
|
74 | + $font = $this->expandCSSEscape($font); |
|
75 | + |
|
76 | + // $font is a pure representation of the font name |
|
77 | + |
|
78 | + if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) { |
|
79 | + continue; |
|
80 | + } |
|
81 | + |
|
82 | + if (ctype_alnum($font) && $font !== '') { |
|
83 | + // very simple font, allow it in unharmed |
|
84 | + $final .= $font . ', '; |
|
85 | + continue; |
|
86 | + } |
|
87 | + |
|
88 | + // bugger out on whitespace. form feed (0C) really |
|
89 | + // shouldn't show up regardless |
|
90 | + $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font); |
|
91 | + |
|
92 | + // Here, there are various classes of characters which need |
|
93 | + // to be treated differently: |
|
94 | + // - Alphanumeric characters are essentially safe. We |
|
95 | + // handled these above. |
|
96 | + // - Spaces require quoting, though most parsers will do |
|
97 | + // the right thing if there aren't any characters that |
|
98 | + // can be misinterpreted |
|
99 | + // - Dashes rarely occur, but they fairly unproblematic |
|
100 | + // for parsing/rendering purposes. |
|
101 | + // The above characters cover the majority of Western font |
|
102 | + // names. |
|
103 | + // - Arbitrary Unicode characters not in ASCII. Because |
|
104 | + // most parsers give little thought to Unicode, treatment |
|
105 | + // of these codepoints is basically uniform, even for |
|
106 | + // punctuation-like codepoints. These characters can |
|
107 | + // show up in non-Western pages and are supported by most |
|
108 | + // major browsers, for example: "MS 明朝" is a |
|
109 | + // legitimate font-name |
|
110 | + // <http://ja.wikipedia.org/wiki/MS_明朝>. See |
|
111 | + // the CSS3 spec for more examples: |
|
112 | + // <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png> |
|
113 | + // You can see live samples of these on the Internet: |
|
114 | + // <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック> |
|
115 | + // However, most of these fonts have ASCII equivalents: |
|
116 | + // for example, 'MS Mincho', and it's considered |
|
117 | + // professional to use ASCII font names instead of |
|
118 | + // Unicode font names. Thanks Takeshi Terada for |
|
119 | + // providing this information. |
|
120 | + // The following characters, to my knowledge, have not been |
|
121 | + // used to name font names. |
|
122 | + // - Single quote. While theoretically you might find a |
|
123 | + // font name that has a single quote in its name (serving |
|
124 | + // as an apostrophe, e.g. Dave's Scribble), I haven't |
|
125 | + // been able to find any actual examples of this. |
|
126 | + // Internet Explorer's cssText translation (which I |
|
127 | + // believe is invoked by innerHTML) normalizes any |
|
128 | + // quoting to single quotes, and fails to escape single |
|
129 | + // quotes. (Note that this is not IE's behavior for all |
|
130 | + // CSS properties, just some sort of special casing for |
|
131 | + // font-family). So a single quote *cannot* be used |
|
132 | + // safely in the font-family context if there will be an |
|
133 | + // innerHTML/cssText translation. Note that Firefox 3.x |
|
134 | + // does this too. |
|
135 | + // - Double quote. In IE, these get normalized to |
|
136 | + // single-quotes, no matter what the encoding. (Fun |
|
137 | + // fact, in IE8, the 'content' CSS property gained |
|
138 | + // support, where they special cased to preserve encoded |
|
139 | + // double quotes, but still translate unadorned double |
|
140 | + // quotes into single quotes.) So, because their |
|
141 | + // fixpoint behavior is identical to single quotes, they |
|
142 | + // cannot be allowed either. Firefox 3.x displays |
|
143 | + // single-quote style behavior. |
|
144 | + // - Backslashes are reduced by one (so \\ -> \) every |
|
145 | + // iteration, so they cannot be used safely. This shows |
|
146 | + // up in IE7, IE8 and FF3 |
|
147 | + // - Semicolons, commas and backticks are handled properly. |
|
148 | + // - The rest of the ASCII punctuation is handled properly. |
|
149 | + // We haven't checked what browsers do to unadorned |
|
150 | + // versions, but this is not important as long as the |
|
151 | + // browser doesn't /remove/ surrounding quotes (as IE does |
|
152 | + // for HTML). |
|
153 | + // |
|
154 | + // With these results in hand, we conclude that there are |
|
155 | + // various levels of safety: |
|
156 | + // - Paranoid: alphanumeric, spaces and dashes(?) |
|
157 | + // - International: Paranoid + non-ASCII Unicode |
|
158 | + // - Edgy: Everything except quotes, backslashes |
|
159 | + // - NoJS: Standards compliance, e.g. sod IE. Note that |
|
160 | + // with some judicious character escaping (since certain |
|
161 | + // types of escaping doesn't work) this is theoretically |
|
162 | + // OK as long as innerHTML/cssText is not called. |
|
163 | + // We believe that international is a reasonable default |
|
164 | + // (that we will implement now), and once we do more |
|
165 | + // extensive research, we may feel comfortable with dropping |
|
166 | + // it down to edgy. |
|
167 | + |
|
168 | + // Edgy: alphanumeric, spaces, dashes and Unicode. Use of |
|
169 | + // str(c)spn assumes that the string was already well formed |
|
170 | + // Unicode (which of course it is). |
|
171 | + if (strspn($font, $this->mask) !== strlen($font)) { |
|
172 | + continue; |
|
173 | + } |
|
174 | + |
|
175 | + // Historical: |
|
176 | + // In the absence of innerHTML/cssText, these ugly |
|
177 | + // transforms don't pose a security risk (as \\ and \" |
|
178 | + // might--these escapes are not supported by most browsers). |
|
179 | + // We could try to be clever and use single-quote wrapping |
|
180 | + // when there is a double quote present, but I have choosen |
|
181 | + // not to implement that. (NOTE: you can reduce the amount |
|
182 | + // of escapes by one depending on what quoting style you use) |
|
183 | + // $font = str_replace('\\', '\\5C ', $font); |
|
184 | + // $font = str_replace('"', '\\22 ', $font); |
|
185 | + // $font = str_replace("'", '\\27 ', $font); |
|
186 | + |
|
187 | + // font possibly with spaces, requires quoting |
|
188 | + $final .= "'$font', "; |
|
189 | + } |
|
190 | + $final = rtrim($final, ', '); |
|
191 | + if ($final === '') return false; |
|
192 | + return $final; |
|
193 | + } |
|
194 | 194 | |
195 | 195 | } |
196 | 196 |
@@ -10,9 +10,16 @@ discard block |
||
10 | 10 | |
11 | 11 | public function __construct() { |
12 | 12 | $this->mask = '- '; |
13 | - for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c; |
|
14 | - for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c; |
|
15 | - for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine |
|
13 | + for ($c = 'a'; $c <= 'z'; $c++) { |
|
14 | + $this->mask .= $c; |
|
15 | + } |
|
16 | + for ($c = 'A'; $c <= 'Z'; $c++) { |
|
17 | + $this->mask .= $c; |
|
18 | + } |
|
19 | + for ($c = '0'; $c <= '9'; $c++) { |
|
20 | + $this->mask .= $c; |
|
21 | + } |
|
22 | + // cast-y, but should be fine |
|
16 | 23 | // special bytes used by UTF-8 |
17 | 24 | for ($i = 0x80; $i <= 0xFF; $i++) { |
18 | 25 | // We don't bother excluding invalid bytes in this range, |
@@ -54,7 +61,9 @@ discard block |
||
54 | 61 | $final = ''; |
55 | 62 | foreach($fonts as $font) { |
56 | 63 | $font = trim($font); |
57 | - if ($font === '') continue; |
|
64 | + if ($font === '') { |
|
65 | + continue; |
|
66 | + } |
|
58 | 67 | // match a generic name |
59 | 68 | if (isset($generic_names[$font])) { |
60 | 69 | if ($allowed_fonts === null || isset($allowed_fonts[$font])) { |
@@ -65,9 +74,13 @@ discard block |
||
65 | 74 | // match a quoted name |
66 | 75 | if ($font[0] === '"' || $font[0] === "'") { |
67 | 76 | $length = strlen($font); |
68 | - if ($length <= 2) continue; |
|
77 | + if ($length <= 2) { |
|
78 | + continue; |
|
79 | + } |
|
69 | 80 | $quote = $font[0]; |
70 | - if ($font[$length - 1] !== $quote) continue; |
|
81 | + if ($font[$length - 1] !== $quote) { |
|
82 | + continue; |
|
83 | + } |
|
71 | 84 | $font = substr($font, 1, $length - 2); |
72 | 85 | } |
73 | 86 | |
@@ -188,7 +201,9 @@ discard block |
||
188 | 201 | $final .= "'$font', "; |
189 | 202 | } |
190 | 203 | $final = rtrim($final, ', '); |
191 | - if ($final === '') return false; |
|
204 | + if ($final === '') { |
|
205 | + return false; |
|
206 | + } |
|
192 | 207 | return $final; |
193 | 208 | } |
194 | 209 |
@@ -52,13 +52,13 @@ discard block |
||
52 | 52 | // assume that no font names contain commas in them |
53 | 53 | $fonts = explode(',', $string); |
54 | 54 | $final = ''; |
55 | - foreach($fonts as $font) { |
|
55 | + foreach ($fonts as $font) { |
|
56 | 56 | $font = trim($font); |
57 | 57 | if ($font === '') continue; |
58 | 58 | // match a generic name |
59 | 59 | if (isset($generic_names[$font])) { |
60 | 60 | if ($allowed_fonts === null || isset($allowed_fonts[$font])) { |
61 | - $final .= $font . ', '; |
|
61 | + $final .= $font.', '; |
|
62 | 62 | } |
63 | 63 | continue; |
64 | 64 | } |
@@ -81,7 +81,7 @@ discard block |
||
81 | 81 | |
82 | 82 | if (ctype_alnum($font) && $font !== '') { |
83 | 83 | // very simple font, allow it in unharmed |
84 | - $final .= $font . ', '; |
|
84 | + $final .= $font.', '; |
|
85 | 85 | continue; |
86 | 86 | } |
87 | 87 |
@@ -6,18 +6,18 @@ |
||
6 | 6 | class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef |
7 | 7 | { |
8 | 8 | |
9 | - public function validate($string, $config, $context) { |
|
9 | + public function validate($string, $config, $context) { |
|
10 | 10 | |
11 | - $string = trim($string); |
|
11 | + $string = trim($string); |
|
12 | 12 | |
13 | - // early abort: '' and '0' (strings that convert to false) are invalid |
|
14 | - if (!$string) return false; |
|
13 | + // early abort: '' and '0' (strings that convert to false) are invalid |
|
14 | + if (!$string) return false; |
|
15 | 15 | |
16 | - $pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/'; |
|
17 | - if (!preg_match($pattern, $string)) return false; |
|
18 | - return $string; |
|
16 | + $pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/'; |
|
17 | + if (!preg_match($pattern, $string)) return false; |
|
18 | + return $string; |
|
19 | 19 | |
20 | - } |
|
20 | + } |
|
21 | 21 | |
22 | 22 | } |
23 | 23 |
@@ -11,10 +11,14 @@ |
||
11 | 11 | $string = trim($string); |
12 | 12 | |
13 | 13 | // early abort: '' and '0' (strings that convert to false) are invalid |
14 | - if (!$string) return false; |
|
14 | + if (!$string) { |
|
15 | + return false; |
|
16 | + } |
|
15 | 17 | |
16 | 18 | $pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/'; |
17 | - if (!preg_match($pattern, $string)) return false; |
|
19 | + if (!preg_match($pattern, $string)) { |
|
20 | + return false; |
|
21 | + } |
|
18 | 22 | return $string; |
19 | 23 | |
20 | 24 | } |
@@ -5,36 +5,36 @@ |
||
5 | 5 | */ |
6 | 6 | class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef |
7 | 7 | { |
8 | - public $def, $allow; |
|
8 | + public $def, $allow; |
|
9 | 9 | |
10 | - /** |
|
11 | - * @param $def Definition to wrap |
|
12 | - * @param $allow Whether or not to allow !important |
|
13 | - */ |
|
14 | - public function __construct($def, $allow = false) { |
|
15 | - $this->def = $def; |
|
16 | - $this->allow = $allow; |
|
17 | - } |
|
18 | - /** |
|
19 | - * Intercepts and removes !important if necessary |
|
20 | - */ |
|
21 | - public function validate($string, $config, $context) { |
|
22 | - // test for ! and important tokens |
|
23 | - $string = trim($string); |
|
24 | - $is_important = false; |
|
25 | - // :TODO: optimization: test directly for !important and ! important |
|
26 | - if (strlen($string) >= 9 && substr($string, -9) === 'important') { |
|
27 | - $temp = rtrim(substr($string, 0, -9)); |
|
28 | - // use a temp, because we might want to restore important |
|
29 | - if (strlen($temp) >= 1 && substr($temp, -1) === '!') { |
|
30 | - $string = rtrim(substr($temp, 0, -1)); |
|
31 | - $is_important = true; |
|
32 | - } |
|
33 | - } |
|
34 | - $string = $this->def->validate($string, $config, $context); |
|
35 | - if ($this->allow && $is_important) $string .= ' !important'; |
|
36 | - return $string; |
|
37 | - } |
|
10 | + /** |
|
11 | + * @param $def Definition to wrap |
|
12 | + * @param $allow Whether or not to allow !important |
|
13 | + */ |
|
14 | + public function __construct($def, $allow = false) { |
|
15 | + $this->def = $def; |
|
16 | + $this->allow = $allow; |
|
17 | + } |
|
18 | + /** |
|
19 | + * Intercepts and removes !important if necessary |
|
20 | + */ |
|
21 | + public function validate($string, $config, $context) { |
|
22 | + // test for ! and important tokens |
|
23 | + $string = trim($string); |
|
24 | + $is_important = false; |
|
25 | + // :TODO: optimization: test directly for !important and ! important |
|
26 | + if (strlen($string) >= 9 && substr($string, -9) === 'important') { |
|
27 | + $temp = rtrim(substr($string, 0, -9)); |
|
28 | + // use a temp, because we might want to restore important |
|
29 | + if (strlen($temp) >= 1 && substr($temp, -1) === '!') { |
|
30 | + $string = rtrim(substr($temp, 0, -1)); |
|
31 | + $is_important = true; |
|
32 | + } |
|
33 | + } |
|
34 | + $string = $this->def->validate($string, $config, $context); |
|
35 | + if ($this->allow && $is_important) $string .= ' !important'; |
|
36 | + return $string; |
|
37 | + } |
|
38 | 38 | } |
39 | 39 | |
40 | 40 | // vim: et sw=4 sts=4 |
@@ -32,7 +32,9 @@ |
||
32 | 32 | } |
33 | 33 | } |
34 | 34 | $string = $this->def->validate($string, $config, $context); |
35 | - if ($this->allow && $is_important) $string .= ' !important'; |
|
35 | + if ($this->allow && $is_important) { |
|
36 | + $string .= ' !important'; |
|
37 | + } |
|
36 | 38 | return $string; |
37 | 39 | } |
38 | 40 | } |
@@ -7,71 +7,71 @@ |
||
7 | 7 | class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef |
8 | 8 | { |
9 | 9 | |
10 | - /** |
|
11 | - * Local copy of component validators. |
|
12 | - * @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl. |
|
13 | - */ |
|
14 | - protected $info; |
|
15 | - |
|
16 | - public function __construct($config) { |
|
17 | - $def = $config->getCSSDefinition(); |
|
18 | - $this->info['list-style-type'] = $def->info['list-style-type']; |
|
19 | - $this->info['list-style-position'] = $def->info['list-style-position']; |
|
20 | - $this->info['list-style-image'] = $def->info['list-style-image']; |
|
21 | - } |
|
22 | - |
|
23 | - public function validate($string, $config, $context) { |
|
24 | - |
|
25 | - // regular pre-processing |
|
26 | - $string = $this->parseCDATA($string); |
|
27 | - if ($string === '') return false; |
|
28 | - |
|
29 | - // assumes URI doesn't have spaces in it |
|
30 | - $bits = explode(' ', strtolower($string)); // bits to process |
|
31 | - |
|
32 | - $caught = array(); |
|
33 | - $caught['type'] = false; |
|
34 | - $caught['position'] = false; |
|
35 | - $caught['image'] = false; |
|
36 | - |
|
37 | - $i = 0; // number of catches |
|
38 | - $none = false; |
|
39 | - |
|
40 | - foreach ($bits as $bit) { |
|
41 | - if ($i >= 3) return; // optimization bit |
|
42 | - if ($bit === '') continue; |
|
43 | - foreach ($caught as $key => $status) { |
|
44 | - if ($status !== false) continue; |
|
45 | - $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); |
|
46 | - if ($r === false) continue; |
|
47 | - if ($r === 'none') { |
|
48 | - if ($none) continue; |
|
49 | - else $none = true; |
|
50 | - if ($key == 'image') continue; |
|
51 | - } |
|
52 | - $caught[$key] = $r; |
|
53 | - $i++; |
|
54 | - break; |
|
55 | - } |
|
56 | - } |
|
57 | - |
|
58 | - if (!$i) return false; |
|
59 | - |
|
60 | - $ret = array(); |
|
61 | - |
|
62 | - // construct type |
|
63 | - if ($caught['type']) $ret[] = $caught['type']; |
|
64 | - |
|
65 | - // construct image |
|
66 | - if ($caught['image']) $ret[] = $caught['image']; |
|
67 | - |
|
68 | - // construct position |
|
69 | - if ($caught['position']) $ret[] = $caught['position']; |
|
70 | - |
|
71 | - if (empty($ret)) return false; |
|
72 | - return implode(' ', $ret); |
|
73 | - |
|
74 | - } |
|
10 | + /** |
|
11 | + * Local copy of component validators. |
|
12 | + * @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl. |
|
13 | + */ |
|
14 | + protected $info; |
|
15 | + |
|
16 | + public function __construct($config) { |
|
17 | + $def = $config->getCSSDefinition(); |
|
18 | + $this->info['list-style-type'] = $def->info['list-style-type']; |
|
19 | + $this->info['list-style-position'] = $def->info['list-style-position']; |
|
20 | + $this->info['list-style-image'] = $def->info['list-style-image']; |
|
21 | + } |
|
22 | + |
|
23 | + public function validate($string, $config, $context) { |
|
24 | + |
|
25 | + // regular pre-processing |
|
26 | + $string = $this->parseCDATA($string); |
|
27 | + if ($string === '') return false; |
|
28 | + |
|
29 | + // assumes URI doesn't have spaces in it |
|
30 | + $bits = explode(' ', strtolower($string)); // bits to process |
|
31 | + |
|
32 | + $caught = array(); |
|
33 | + $caught['type'] = false; |
|
34 | + $caught['position'] = false; |
|
35 | + $caught['image'] = false; |
|
36 | + |
|
37 | + $i = 0; // number of catches |
|
38 | + $none = false; |
|
39 | + |
|
40 | + foreach ($bits as $bit) { |
|
41 | + if ($i >= 3) return; // optimization bit |
|
42 | + if ($bit === '') continue; |
|
43 | + foreach ($caught as $key => $status) { |
|
44 | + if ($status !== false) continue; |
|
45 | + $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); |
|
46 | + if ($r === false) continue; |
|
47 | + if ($r === 'none') { |
|
48 | + if ($none) continue; |
|
49 | + else $none = true; |
|
50 | + if ($key == 'image') continue; |
|
51 | + } |
|
52 | + $caught[$key] = $r; |
|
53 | + $i++; |
|
54 | + break; |
|
55 | + } |
|
56 | + } |
|
57 | + |
|
58 | + if (!$i) return false; |
|
59 | + |
|
60 | + $ret = array(); |
|
61 | + |
|
62 | + // construct type |
|
63 | + if ($caught['type']) $ret[] = $caught['type']; |
|
64 | + |
|
65 | + // construct image |
|
66 | + if ($caught['image']) $ret[] = $caught['image']; |
|
67 | + |
|
68 | + // construct position |
|
69 | + if ($caught['position']) $ret[] = $caught['position']; |
|
70 | + |
|
71 | + if (empty($ret)) return false; |
|
72 | + return implode(' ', $ret); |
|
73 | + |
|
74 | + } |
|
75 | 75 | |
76 | 76 | } |
77 | 77 |
@@ -24,7 +24,9 @@ discard block |
||
24 | 24 | |
25 | 25 | // regular pre-processing |
26 | 26 | $string = $this->parseCDATA($string); |
27 | - if ($string === '') return false; |
|
27 | + if ($string === '') { |
|
28 | + return false; |
|
29 | + } |
|
28 | 30 | |
29 | 31 | // assumes URI doesn't have spaces in it |
30 | 32 | $bits = explode(' ', strtolower($string)); // bits to process |
@@ -38,16 +40,30 @@ discard block |
||
38 | 40 | $none = false; |
39 | 41 | |
40 | 42 | foreach ($bits as $bit) { |
41 | - if ($i >= 3) return; // optimization bit |
|
42 | - if ($bit === '') continue; |
|
43 | + if ($i >= 3) { |
|
44 | + return; |
|
45 | + } |
|
46 | + // optimization bit |
|
47 | + if ($bit === '') { |
|
48 | + continue; |
|
49 | + } |
|
43 | 50 | foreach ($caught as $key => $status) { |
44 | - if ($status !== false) continue; |
|
51 | + if ($status !== false) { |
|
52 | + continue; |
|
53 | + } |
|
45 | 54 | $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); |
46 | - if ($r === false) continue; |
|
55 | + if ($r === false) { |
|
56 | + continue; |
|
57 | + } |
|
47 | 58 | if ($r === 'none') { |
48 | - if ($none) continue; |
|
49 | - else $none = true; |
|
50 | - if ($key == 'image') continue; |
|
59 | + if ($none) { |
|
60 | + continue; |
|
61 | + } else { |
|
62 | + $none = true; |
|
63 | + } |
|
64 | + if ($key == 'image') { |
|
65 | + continue; |
|
66 | + } |
|
51 | 67 | } |
52 | 68 | $caught[$key] = $r; |
53 | 69 | $i++; |
@@ -55,20 +71,30 @@ discard block |
||
55 | 71 | } |
56 | 72 | } |
57 | 73 | |
58 | - if (!$i) return false; |
|
74 | + if (!$i) { |
|
75 | + return false; |
|
76 | + } |
|
59 | 77 | |
60 | 78 | $ret = array(); |
61 | 79 | |
62 | 80 | // construct type |
63 | - if ($caught['type']) $ret[] = $caught['type']; |
|
81 | + if ($caught['type']) { |
|
82 | + $ret[] = $caught['type']; |
|
83 | + } |
|
64 | 84 | |
65 | 85 | // construct image |
66 | - if ($caught['image']) $ret[] = $caught['image']; |
|
86 | + if ($caught['image']) { |
|
87 | + $ret[] = $caught['image']; |
|
88 | + } |
|
67 | 89 | |
68 | 90 | // construct position |
69 | - if ($caught['position']) $ret[] = $caught['position']; |
|
91 | + if ($caught['position']) { |
|
92 | + $ret[] = $caught['position']; |
|
93 | + } |
|
70 | 94 | |
71 | - if (empty($ret)) return false; |
|
95 | + if (empty($ret)) { |
|
96 | + return false; |
|
97 | + } |
|
72 | 98 | return implode(' ', $ret); |
73 | 99 | |
74 | 100 | } |
@@ -42,7 +42,7 @@ |
||
42 | 42 | if ($bit === '') continue; |
43 | 43 | foreach ($caught as $key => $status) { |
44 | 44 | if ($status !== false) continue; |
45 | - $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); |
|
45 | + $r = $this->info['list-style-'.$key]->validate($bit, $config, $context); |
|
46 | 46 | if ($r === false) continue; |
47 | 47 | if ($r === 'none') { |
48 | 48 | if ($none) continue; |
@@ -14,44 +14,44 @@ |
||
14 | 14 | class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * Instance of component definition to defer validation to. |
|
19 | - * @todo Make protected |
|
20 | - */ |
|
21 | - public $single; |
|
17 | + /** |
|
18 | + * Instance of component definition to defer validation to. |
|
19 | + * @todo Make protected |
|
20 | + */ |
|
21 | + public $single; |
|
22 | 22 | |
23 | - /** |
|
24 | - * Max number of values allowed. |
|
25 | - * @todo Make protected |
|
26 | - */ |
|
27 | - public $max; |
|
23 | + /** |
|
24 | + * Max number of values allowed. |
|
25 | + * @todo Make protected |
|
26 | + */ |
|
27 | + public $max; |
|
28 | 28 | |
29 | - /** |
|
30 | - * @param $single HTMLPurifier_AttrDef to multiply |
|
31 | - * @param $max Max number of values allowed (usually four) |
|
32 | - */ |
|
33 | - public function __construct($single, $max = 4) { |
|
34 | - $this->single = $single; |
|
35 | - $this->max = $max; |
|
36 | - } |
|
29 | + /** |
|
30 | + * @param $single HTMLPurifier_AttrDef to multiply |
|
31 | + * @param $max Max number of values allowed (usually four) |
|
32 | + */ |
|
33 | + public function __construct($single, $max = 4) { |
|
34 | + $this->single = $single; |
|
35 | + $this->max = $max; |
|
36 | + } |
|
37 | 37 | |
38 | - public function validate($string, $config, $context) { |
|
39 | - $string = $this->parseCDATA($string); |
|
40 | - if ($string === '') return false; |
|
41 | - $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n |
|
42 | - $length = count($parts); |
|
43 | - $final = ''; |
|
44 | - for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { |
|
45 | - if (ctype_space($parts[$i])) continue; |
|
46 | - $result = $this->single->validate($parts[$i], $config, $context); |
|
47 | - if ($result !== false) { |
|
48 | - $final .= $result . ' '; |
|
49 | - $num++; |
|
50 | - } |
|
51 | - } |
|
52 | - if ($final === '') return false; |
|
53 | - return rtrim($final); |
|
54 | - } |
|
38 | + public function validate($string, $config, $context) { |
|
39 | + $string = $this->parseCDATA($string); |
|
40 | + if ($string === '') return false; |
|
41 | + $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n |
|
42 | + $length = count($parts); |
|
43 | + $final = ''; |
|
44 | + for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { |
|
45 | + if (ctype_space($parts[$i])) continue; |
|
46 | + $result = $this->single->validate($parts[$i], $config, $context); |
|
47 | + if ($result !== false) { |
|
48 | + $final .= $result . ' '; |
|
49 | + $num++; |
|
50 | + } |
|
51 | + } |
|
52 | + if ($final === '') return false; |
|
53 | + return rtrim($final); |
|
54 | + } |
|
55 | 55 | |
56 | 56 | } |
57 | 57 |
@@ -37,19 +37,25 @@ |
||
37 | 37 | |
38 | 38 | public function validate($string, $config, $context) { |
39 | 39 | $string = $this->parseCDATA($string); |
40 | - if ($string === '') return false; |
|
40 | + if ($string === '') { |
|
41 | + return false; |
|
42 | + } |
|
41 | 43 | $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n |
42 | 44 | $length = count($parts); |
43 | 45 | $final = ''; |
44 | 46 | for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { |
45 | - if (ctype_space($parts[$i])) continue; |
|
47 | + if (ctype_space($parts[$i])) { |
|
48 | + continue; |
|
49 | + } |
|
46 | 50 | $result = $this->single->validate($parts[$i], $config, $context); |
47 | 51 | if ($result !== false) { |
48 | 52 | $final .= $result . ' '; |
49 | 53 | $num++; |
50 | 54 | } |
51 | 55 | } |
52 | - if ($final === '') return false; |
|
56 | + if ($final === '') { |
|
57 | + return false; |
|
58 | + } |
|
53 | 59 | return rtrim($final); |
54 | 60 | } |
55 | 61 |
@@ -45,7 +45,7 @@ |
||
45 | 45 | if (ctype_space($parts[$i])) continue; |
46 | 46 | $result = $this->single->validate($parts[$i], $config, $context); |
47 | 47 | if ($result !== false) { |
48 | - $final .= $result . ' '; |
|
48 | + $final .= $result.' '; |
|
49 | 49 | $num++; |
50 | 50 | } |
51 | 51 | } |
@@ -6,63 +6,63 @@ |
||
6 | 6 | class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef |
7 | 7 | { |
8 | 8 | |
9 | - /** |
|
10 | - * Bool indicating whether or not only positive values allowed. |
|
11 | - */ |
|
12 | - protected $non_negative = false; |
|
13 | - |
|
14 | - /** |
|
15 | - * @param $non_negative Bool indicating whether negatives are forbidden |
|
16 | - */ |
|
17 | - public function __construct($non_negative = false) { |
|
18 | - $this->non_negative = $non_negative; |
|
19 | - } |
|
20 | - |
|
21 | - /** |
|
22 | - * @warning Some contexts do not pass $config, $context. These |
|
23 | - * variables should not be used without checking HTMLPurifier_Length |
|
24 | - */ |
|
25 | - public function validate($number, $config, $context) { |
|
26 | - |
|
27 | - $number = $this->parseCDATA($number); |
|
28 | - |
|
29 | - if ($number === '') return false; |
|
30 | - if ($number === '0') return '0'; |
|
31 | - |
|
32 | - $sign = ''; |
|
33 | - switch ($number[0]) { |
|
34 | - case '-': |
|
35 | - if ($this->non_negative) return false; |
|
36 | - $sign = '-'; |
|
37 | - case '+': |
|
38 | - $number = substr($number, 1); |
|
39 | - } |
|
40 | - |
|
41 | - if (ctype_digit($number)) { |
|
42 | - $number = ltrim($number, '0'); |
|
43 | - return $number ? $sign . $number : '0'; |
|
44 | - } |
|
45 | - |
|
46 | - // Period is the only non-numeric character allowed |
|
47 | - if (strpos($number, '.') === false) return false; |
|
48 | - |
|
49 | - list($left, $right) = explode('.', $number, 2); |
|
50 | - |
|
51 | - if ($left === '' && $right === '') return false; |
|
52 | - if ($left !== '' && !ctype_digit($left)) return false; |
|
53 | - |
|
54 | - $left = ltrim($left, '0'); |
|
55 | - $right = rtrim($right, '0'); |
|
56 | - |
|
57 | - if ($right === '') { |
|
58 | - return $left ? $sign . $left : '0'; |
|
59 | - } elseif (!ctype_digit($right)) { |
|
60 | - return false; |
|
61 | - } |
|
62 | - |
|
63 | - return $sign . $left . '.' . $right; |
|
64 | - |
|
65 | - } |
|
9 | + /** |
|
10 | + * Bool indicating whether or not only positive values allowed. |
|
11 | + */ |
|
12 | + protected $non_negative = false; |
|
13 | + |
|
14 | + /** |
|
15 | + * @param $non_negative Bool indicating whether negatives are forbidden |
|
16 | + */ |
|
17 | + public function __construct($non_negative = false) { |
|
18 | + $this->non_negative = $non_negative; |
|
19 | + } |
|
20 | + |
|
21 | + /** |
|
22 | + * @warning Some contexts do not pass $config, $context. These |
|
23 | + * variables should not be used without checking HTMLPurifier_Length |
|
24 | + */ |
|
25 | + public function validate($number, $config, $context) { |
|
26 | + |
|
27 | + $number = $this->parseCDATA($number); |
|
28 | + |
|
29 | + if ($number === '') return false; |
|
30 | + if ($number === '0') return '0'; |
|
31 | + |
|
32 | + $sign = ''; |
|
33 | + switch ($number[0]) { |
|
34 | + case '-': |
|
35 | + if ($this->non_negative) return false; |
|
36 | + $sign = '-'; |
|
37 | + case '+': |
|
38 | + $number = substr($number, 1); |
|
39 | + } |
|
40 | + |
|
41 | + if (ctype_digit($number)) { |
|
42 | + $number = ltrim($number, '0'); |
|
43 | + return $number ? $sign . $number : '0'; |
|
44 | + } |
|
45 | + |
|
46 | + // Period is the only non-numeric character allowed |
|
47 | + if (strpos($number, '.') === false) return false; |
|
48 | + |
|
49 | + list($left, $right) = explode('.', $number, 2); |
|
50 | + |
|
51 | + if ($left === '' && $right === '') return false; |
|
52 | + if ($left !== '' && !ctype_digit($left)) return false; |
|
53 | + |
|
54 | + $left = ltrim($left, '0'); |
|
55 | + $right = rtrim($right, '0'); |
|
56 | + |
|
57 | + if ($right === '') { |
|
58 | + return $left ? $sign . $left : '0'; |
|
59 | + } elseif (!ctype_digit($right)) { |
|
60 | + return false; |
|
61 | + } |
|
62 | + |
|
63 | + return $sign . $left . '.' . $right; |
|
64 | + |
|
65 | + } |
|
66 | 66 | |
67 | 67 | } |
68 | 68 |
@@ -26,13 +26,19 @@ discard block |
||
26 | 26 | |
27 | 27 | $number = $this->parseCDATA($number); |
28 | 28 | |
29 | - if ($number === '') return false; |
|
30 | - if ($number === '0') return '0'; |
|
29 | + if ($number === '') { |
|
30 | + return false; |
|
31 | + } |
|
32 | + if ($number === '0') { |
|
33 | + return '0'; |
|
34 | + } |
|
31 | 35 | |
32 | 36 | $sign = ''; |
33 | 37 | switch ($number[0]) { |
34 | 38 | case '-': |
35 | - if ($this->non_negative) return false; |
|
39 | + if ($this->non_negative) { |
|
40 | + return false; |
|
41 | + } |
|
36 | 42 | $sign = '-'; |
37 | 43 | case '+': |
38 | 44 | $number = substr($number, 1); |
@@ -44,12 +50,18 @@ discard block |
||
44 | 50 | } |
45 | 51 | |
46 | 52 | // Period is the only non-numeric character allowed |
47 | - if (strpos($number, '.') === false) return false; |
|
53 | + if (strpos($number, '.') === false) { |
|
54 | + return false; |
|
55 | + } |
|
48 | 56 | |
49 | 57 | list($left, $right) = explode('.', $number, 2); |
50 | 58 | |
51 | - if ($left === '' && $right === '') return false; |
|
52 | - if ($left !== '' && !ctype_digit($left)) return false; |
|
59 | + if ($left === '' && $right === '') { |
|
60 | + return false; |
|
61 | + } |
|
62 | + if ($left !== '' && !ctype_digit($left)) { |
|
63 | + return false; |
|
64 | + } |
|
53 | 65 | |
54 | 66 | $left = ltrim($left, '0'); |
55 | 67 | $right = rtrim($right, '0'); |
@@ -40,7 +40,7 @@ discard block |
||
40 | 40 | |
41 | 41 | if (ctype_digit($number)) { |
42 | 42 | $number = ltrim($number, '0'); |
43 | - return $number ? $sign . $number : '0'; |
|
43 | + return $number ? $sign.$number : '0'; |
|
44 | 44 | } |
45 | 45 | |
46 | 46 | // Period is the only non-numeric character allowed |
@@ -51,16 +51,16 @@ discard block |
||
51 | 51 | if ($left === '' && $right === '') return false; |
52 | 52 | if ($left !== '' && !ctype_digit($left)) return false; |
53 | 53 | |
54 | - $left = ltrim($left, '0'); |
|
54 | + $left = ltrim($left, '0'); |
|
55 | 55 | $right = rtrim($right, '0'); |
56 | 56 | |
57 | 57 | if ($right === '') { |
58 | - return $left ? $sign . $left : '0'; |
|
58 | + return $left ? $sign.$left : '0'; |
|
59 | 59 | } elseif (!ctype_digit($right)) { |
60 | 60 | return false; |
61 | 61 | } |
62 | 62 | |
63 | - return $sign . $left . '.' . $right; |
|
63 | + return $sign.$left.'.'.$right; |
|
64 | 64 | |
65 | 65 | } |
66 | 66 |
@@ -6,34 +6,34 @@ |
||
6 | 6 | class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef |
7 | 7 | { |
8 | 8 | |
9 | - /** |
|
10 | - * Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation |
|
11 | - */ |
|
12 | - protected $number_def; |
|
9 | + /** |
|
10 | + * Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation |
|
11 | + */ |
|
12 | + protected $number_def; |
|
13 | 13 | |
14 | - /** |
|
15 | - * @param Bool indicating whether to forbid negative values |
|
16 | - */ |
|
17 | - public function __construct($non_negative = false) { |
|
18 | - $this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative); |
|
19 | - } |
|
14 | + /** |
|
15 | + * @param Bool indicating whether to forbid negative values |
|
16 | + */ |
|
17 | + public function __construct($non_negative = false) { |
|
18 | + $this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative); |
|
19 | + } |
|
20 | 20 | |
21 | - public function validate($string, $config, $context) { |
|
21 | + public function validate($string, $config, $context) { |
|
22 | 22 | |
23 | - $string = $this->parseCDATA($string); |
|
23 | + $string = $this->parseCDATA($string); |
|
24 | 24 | |
25 | - if ($string === '') return false; |
|
26 | - $length = strlen($string); |
|
27 | - if ($length === 1) return false; |
|
28 | - if ($string[$length - 1] !== '%') return false; |
|
25 | + if ($string === '') return false; |
|
26 | + $length = strlen($string); |
|
27 | + if ($length === 1) return false; |
|
28 | + if ($string[$length - 1] !== '%') return false; |
|
29 | 29 | |
30 | - $number = substr($string, 0, $length - 1); |
|
31 | - $number = $this->number_def->validate($number, $config, $context); |
|
30 | + $number = substr($string, 0, $length - 1); |
|
31 | + $number = $this->number_def->validate($number, $config, $context); |
|
32 | 32 | |
33 | - if ($number === false) return false; |
|
34 | - return "$number%"; |
|
33 | + if ($number === false) return false; |
|
34 | + return "$number%"; |
|
35 | 35 | |
36 | - } |
|
36 | + } |
|
37 | 37 | |
38 | 38 | } |
39 | 39 |
@@ -22,15 +22,23 @@ |
||
22 | 22 | |
23 | 23 | $string = $this->parseCDATA($string); |
24 | 24 | |
25 | - if ($string === '') return false; |
|
25 | + if ($string === '') { |
|
26 | + return false; |
|
27 | + } |
|
26 | 28 | $length = strlen($string); |
27 | - if ($length === 1) return false; |
|
28 | - if ($string[$length - 1] !== '%') return false; |
|
29 | + if ($length === 1) { |
|
30 | + return false; |
|
31 | + } |
|
32 | + if ($string[$length - 1] !== '%') { |
|
33 | + return false; |
|
34 | + } |
|
29 | 35 | |
30 | 36 | $number = substr($string, 0, $length - 1); |
31 | 37 | $number = $this->number_def->validate($number, $config, $context); |
32 | 38 | |
33 | - if ($number === false) return false; |
|
39 | + if ($number === false) { |
|
40 | + return false; |
|
41 | + } |
|
34 | 42 | return "$number%"; |
35 | 43 | |
36 | 44 | } |
@@ -8,30 +8,30 @@ |
||
8 | 8 | class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef |
9 | 9 | { |
10 | 10 | |
11 | - public function validate($string, $config, $context) { |
|
12 | - |
|
13 | - static $allowed_values = array( |
|
14 | - 'line-through' => true, |
|
15 | - 'overline' => true, |
|
16 | - 'underline' => true, |
|
17 | - ); |
|
18 | - |
|
19 | - $string = strtolower($this->parseCDATA($string)); |
|
20 | - |
|
21 | - if ($string === 'none') return $string; |
|
22 | - |
|
23 | - $parts = explode(' ', $string); |
|
24 | - $final = ''; |
|
25 | - foreach ($parts as $part) { |
|
26 | - if (isset($allowed_values[$part])) { |
|
27 | - $final .= $part . ' '; |
|
28 | - } |
|
29 | - } |
|
30 | - $final = rtrim($final); |
|
31 | - if ($final === '') return false; |
|
32 | - return $final; |
|
33 | - |
|
34 | - } |
|
11 | + public function validate($string, $config, $context) { |
|
12 | + |
|
13 | + static $allowed_values = array( |
|
14 | + 'line-through' => true, |
|
15 | + 'overline' => true, |
|
16 | + 'underline' => true, |
|
17 | + ); |
|
18 | + |
|
19 | + $string = strtolower($this->parseCDATA($string)); |
|
20 | + |
|
21 | + if ($string === 'none') return $string; |
|
22 | + |
|
23 | + $parts = explode(' ', $string); |
|
24 | + $final = ''; |
|
25 | + foreach ($parts as $part) { |
|
26 | + if (isset($allowed_values[$part])) { |
|
27 | + $final .= $part . ' '; |
|
28 | + } |
|
29 | + } |
|
30 | + $final = rtrim($final); |
|
31 | + if ($final === '') return false; |
|
32 | + return $final; |
|
33 | + |
|
34 | + } |
|
35 | 35 | |
36 | 36 | } |
37 | 37 |
@@ -18,7 +18,9 @@ discard block |
||
18 | 18 | |
19 | 19 | $string = strtolower($this->parseCDATA($string)); |
20 | 20 | |
21 | - if ($string === 'none') return $string; |
|
21 | + if ($string === 'none') { |
|
22 | + return $string; |
|
23 | + } |
|
22 | 24 | |
23 | 25 | $parts = explode(' ', $string); |
24 | 26 | $final = ''; |
@@ -28,7 +30,9 @@ discard block |
||
28 | 30 | } |
29 | 31 | } |
30 | 32 | $final = rtrim($final); |
31 | - if ($final === '') return false; |
|
33 | + if ($final === '') { |
|
34 | + return false; |
|
35 | + } |
|
32 | 36 | return $final; |
33 | 37 | |
34 | 38 | } |
@@ -24,7 +24,7 @@ |
||
24 | 24 | $final = ''; |
25 | 25 | foreach ($parts as $part) { |
26 | 26 | if (isset($allowed_values[$part])) { |
27 | - $final .= $part . ' '; |
|
27 | + $final .= $part.' '; |
|
28 | 28 | } |
29 | 29 | } |
30 | 30 | $final = rtrim($final); |
@@ -12,49 +12,49 @@ |
||
12 | 12 | class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI |
13 | 13 | { |
14 | 14 | |
15 | - public function __construct() { |
|
16 | - parent::__construct(true); // always embedded |
|
17 | - } |
|
15 | + public function __construct() { |
|
16 | + parent::__construct(true); // always embedded |
|
17 | + } |
|
18 | 18 | |
19 | - public function validate($uri_string, $config, $context) { |
|
20 | - // parse the URI out of the string and then pass it onto |
|
21 | - // the parent object |
|
19 | + public function validate($uri_string, $config, $context) { |
|
20 | + // parse the URI out of the string and then pass it onto |
|
21 | + // the parent object |
|
22 | 22 | |
23 | - $uri_string = $this->parseCDATA($uri_string); |
|
24 | - if (strpos($uri_string, 'url(') !== 0) return false; |
|
25 | - $uri_string = substr($uri_string, 4); |
|
26 | - $new_length = strlen($uri_string) - 1; |
|
27 | - if ($uri_string[$new_length] != ')') return false; |
|
28 | - $uri = trim(substr($uri_string, 0, $new_length)); |
|
23 | + $uri_string = $this->parseCDATA($uri_string); |
|
24 | + if (strpos($uri_string, 'url(') !== 0) return false; |
|
25 | + $uri_string = substr($uri_string, 4); |
|
26 | + $new_length = strlen($uri_string) - 1; |
|
27 | + if ($uri_string[$new_length] != ')') return false; |
|
28 | + $uri = trim(substr($uri_string, 0, $new_length)); |
|
29 | 29 | |
30 | - if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { |
|
31 | - $quote = $uri[0]; |
|
32 | - $new_length = strlen($uri) - 1; |
|
33 | - if ($uri[$new_length] !== $quote) return false; |
|
34 | - $uri = substr($uri, 1, $new_length - 1); |
|
35 | - } |
|
30 | + if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { |
|
31 | + $quote = $uri[0]; |
|
32 | + $new_length = strlen($uri) - 1; |
|
33 | + if ($uri[$new_length] !== $quote) return false; |
|
34 | + $uri = substr($uri, 1, $new_length - 1); |
|
35 | + } |
|
36 | 36 | |
37 | - $uri = $this->expandCSSEscape($uri); |
|
37 | + $uri = $this->expandCSSEscape($uri); |
|
38 | 38 | |
39 | - $result = parent::validate($uri, $config, $context); |
|
39 | + $result = parent::validate($uri, $config, $context); |
|
40 | 40 | |
41 | - if ($result === false) return false; |
|
41 | + if ($result === false) return false; |
|
42 | 42 | |
43 | - // extra sanity check; should have been done by URI |
|
44 | - $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); |
|
43 | + // extra sanity check; should have been done by URI |
|
44 | + $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); |
|
45 | 45 | |
46 | - // suspicious characters are ()'; we're going to percent encode |
|
47 | - // them for safety. |
|
48 | - $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result); |
|
46 | + // suspicious characters are ()'; we're going to percent encode |
|
47 | + // them for safety. |
|
48 | + $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result); |
|
49 | 49 | |
50 | - // there's an extra bug where ampersands lose their escaping on |
|
51 | - // an innerHTML cycle, so a very unlucky query parameter could |
|
52 | - // then change the meaning of the URL. Unfortunately, there's |
|
53 | - // not much we can do about that... |
|
50 | + // there's an extra bug where ampersands lose their escaping on |
|
51 | + // an innerHTML cycle, so a very unlucky query parameter could |
|
52 | + // then change the meaning of the URL. Unfortunately, there's |
|
53 | + // not much we can do about that... |
|
54 | 54 | |
55 | - return "url(\"$result\")"; |
|
55 | + return "url(\"$result\")"; |
|
56 | 56 | |
57 | - } |
|
57 | + } |
|
58 | 58 | |
59 | 59 | } |
60 | 60 |
@@ -21,16 +21,22 @@ discard block |
||
21 | 21 | // the parent object |
22 | 22 | |
23 | 23 | $uri_string = $this->parseCDATA($uri_string); |
24 | - if (strpos($uri_string, 'url(') !== 0) return false; |
|
24 | + if (strpos($uri_string, 'url(') !== 0) { |
|
25 | + return false; |
|
26 | + } |
|
25 | 27 | $uri_string = substr($uri_string, 4); |
26 | 28 | $new_length = strlen($uri_string) - 1; |
27 | - if ($uri_string[$new_length] != ')') return false; |
|
29 | + if ($uri_string[$new_length] != ')') { |
|
30 | + return false; |
|
31 | + } |
|
28 | 32 | $uri = trim(substr($uri_string, 0, $new_length)); |
29 | 33 | |
30 | 34 | if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { |
31 | 35 | $quote = $uri[0]; |
32 | 36 | $new_length = strlen($uri) - 1; |
33 | - if ($uri[$new_length] !== $quote) return false; |
|
37 | + if ($uri[$new_length] !== $quote) { |
|
38 | + return false; |
|
39 | + } |
|
34 | 40 | $uri = substr($uri, 1, $new_length - 1); |
35 | 41 | } |
36 | 42 | |
@@ -38,7 +44,9 @@ discard block |
||
38 | 44 | |
39 | 45 | $result = parent::validate($uri, $config, $context); |
40 | 46 | |
41 | - if ($result === false) return false; |
|
47 | + if ($result === false) { |
|
48 | + return false; |
|
49 | + } |
|
42 | 50 | |
43 | 51 | // extra sanity check; should have been done by URI |
44 | 52 | $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); |