17 public function testDecodeNamedEntities() {
20 Sanitizer::decodeCharReferences(
'école' ),
21 'decode named entities'
28 public function testDecodeNumericEntities() {
30 "\xc4\x88io bonas dans l'\xc3\xa9cole!",
31 Sanitizer::decodeCharReferences(
"Ĉio bonas dans l'école!" ),
32 'decode numeric entities'
39 public function testDecodeMixedEntities() {
41 "\xc4\x88io bonas dans l'\xc3\xa9cole!",
42 Sanitizer::decodeCharReferences(
"Ĉio bonas dans l'école!" ),
43 'decode mixed numeric/named entities'
50 public function testDecodeMixedComplexEntities() {
52 "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)",
53 Sanitizer::decodeCharReferences(
54 "Ĉio bonas dans l'école! (mais pas Ĉio dans l'école)"
56 'decode mixed complex entities'
63 public function testInvalidAmpersand() {
66 Sanitizer::decodeCharReferences(
'a & b' ),
74 public function testInvalidEntities() {
77 Sanitizer::decodeCharReferences(
'&foo;' ),
78 'Invalid named entity'
85 public function testInvalidNumberedEntities() {
88 Sanitizer::decodeCharReferences(
"�" ),
89 'Invalid numbered entity'
100 public function testRemovehtmltagsOnHtml5Tags(
$tag, $escaped ) {
104 $this->assertEquals(
"<$tag>",
105 Sanitizer::removeHTMLtags(
"<$tag>" )
108 $this->assertEquals(
"<$tag></$tag>\n",
109 Sanitizer::removeHTMLtags(
"<$tag>" )
117 public static function provideHtml5Tags() {
118 $ESCAPED =
true; # We want
tag to be escaped
119 $VERBATIM =
false; # We want to keep the
tag
121 [
'data', $VERBATIM ],
122 [
'mark', $VERBATIM ],
123 [
'time', $VERBATIM ],
124 [
'video', $ESCAPED ],
128 function dataRemoveHTMLtags() {
132 '<div>Hello world</div />',
133 '<div>Hello world</div>',
134 'Self-closing closing div'
139 '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>',
140 '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>',
145 '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>',
146 '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>',
151 '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>',
152 '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>',
153 '<abbr> inside <dfn>',
162 public function testRemoveHTMLtags(
$input,
$output, $msg =
null ) {
164 $this->assertEquals(
$output, Sanitizer::removeHTMLtags(
$input ), $msg );
171 public function testDecodeTagAttributes( $expected, $attributes, $message =
'' ) {
172 $this->assertEquals( $expected,
173 Sanitizer::decodeTagAttributes( $attributes ),
178 public static function provideTagAttributesToDecode() {
180 [ [
'foo' =>
'bar' ],
'foo=bar',
'Unquoted attribute' ],
181 [ [
'foo' =>
'bar' ],
' foo = bar ',
'Spaced attribute' ],
182 [ [
'foo' =>
'bar' ],
'foo="bar"',
'Double-quoted attribute' ],
183 [ [
'foo' =>
'bar' ],
'foo=\'bar\'',
'Single-quoted attribute' ],
185 [
'foo' =>
'bar',
'baz' =>
'foo' ],
186 'foo=\'bar\' baz="foo"',
190 [
'foo' =>
'bar',
'baz' =>
'foo' ],
191 'foo=\'bar\' baz="foo"',
195 [
'foo' =>
'bar',
'baz' =>
'foo' ],
196 'foo=\'bar\' baz="foo"',
199 [ [
':foo' =>
'bar' ],
':foo=\'bar\'',
'Leading :' ],
200 [ [
'_foo' =>
'bar' ],
'_foo=\'bar\'',
'Leading _' ],
201 [ [
'foo' =>
'bar' ],
'Foo=\'bar\'',
'Leading capital' ],
202 [ [
'foo' =>
'BAR' ],
'FOO=BAR',
'Attribute keys are normalized to lowercase' ],
205 [ [],
'-foo=bar',
'Leading - is forbidden' ],
206 [ [],
'.foo=bar',
'Leading . is forbidden' ],
207 [ [
'foo-bar' =>
'bar' ],
'foo-bar=bar',
'A - is allowed inside the attribute' ],
208 [ [
'foo-' =>
'bar' ],
'foo-=bar',
'A - is allowed inside the attribute' ],
209 [ [
'foo.bar' =>
'baz' ],
'foo.bar=baz',
'A . is allowed inside the attribute' ],
210 [ [
'foo.' =>
'baz' ],
'foo.=baz',
'A . is allowed as last character' ],
211 [ [
'foo6' =>
'baz' ],
'foo6=baz',
'Numbers are allowed' ],
213 # This bit is more relaxed than XML rules, but some extensions use
214 # it, like ProofreadPage (see T29539)
215 [ [
'1foo' =>
'baz' ],
'1foo=baz',
'Leading numbers are allowed' ],
216 [ [],
'foo$=baz',
'Symbols are not allowed' ],
217 [ [],
'foo@=baz',
'Symbols are not allowed' ],
218 [ [],
'foo~=baz',
'Symbols are not allowed' ],
220 [
'foo' =>
'1[#^`*%w/(' ],
222 'All kind of characters are allowed as values'
225 [
'foo' =>
'1[#^`*%\'w/(' ],
226 'foo="1[#^`*%\'w/("',
227 'Double quotes are allowed if quoted by single quotes'
230 [
'foo' =>
'1[#^`*%"w/(' ],
231 'foo=\'1[#^`*%"w/(\'',
232 'Single quotes are allowed if quoted by double quotes'
234 [ [
'foo' =>
'&"' ],
'foo=&"',
'Special chars can be provided as entities' ],
235 [ [
'foo' =>
'&foobar;' ],
'foo=&foobar;',
'Entity-like items are accepted' ],
243 public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message =
'' ) {
244 $this->assertEquals(
" $inputAttr",
245 Sanitizer::fixTagAttributes( $inputAttr, $inputEl ),
250 public static function provideDeprecatedAttributes() {
253 [
'clear="left"',
'br' ],
254 [
'clear="all"',
'br' ],
255 [
'width="100"',
'td' ],
256 [
'nowrap="true"',
'td' ],
257 [
'nowrap=""',
'td' ],
258 [
'align="right"',
'td' ],
259 [
'align="center"',
'table' ],
260 [
'align="left"',
'tr' ],
261 [
'align="center"',
'div' ],
262 [
'align="left"',
'h1' ],
263 [
'align="left"',
'p' ],
271 public function testCssCommentsChecking( $expected,
$css, $message =
'' ) {
272 $this->assertEquals( $expected,
273 Sanitizer::checkCss(
$css ),
278 public static function provideCssCommentsFixtures() {
283 [
'/* comment */',
'/* comment */' ],
287 [
'display: block;',
"display:/* foo */block;" ],
288 [
'display: block;',
"display:\\2f\\2a foo \\2a\\2f block;",
289 'Backslash-escaped comments must be stripped (T30450)' ],
290 [
'',
'/* unfinished comment structure',
291 'Remove anything after a comment-start token' ],
292 [
'',
"\\2f\\2a unifinished comment'",
293 'Remove anything after a backslash-escaped comment-start token' ],
295 '/* insecure input */',
296 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader'
297 .
'(src=\'asdf.png\',sizingMethod=\'scale\');'
300 '/* insecure input */',
301 '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader'
302 .
'(src=\'asdf.png\',sizingMethod=\'scale\')";'
304 [
'/* insecure input */',
'width: expression(1+1);' ],
305 [
'/* insecure input */',
'background-image: image(asdf.png);' ],
306 [
'/* insecure input */',
'background-image: -webkit-image(asdf.png);' ],
307 [
'/* insecure input */',
'background-image: -moz-image(asdf.png);' ],
308 [
'/* insecure input */',
'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ],
310 '/* insecure input */',
311 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);'
314 '/* insecure input */',
315 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'
317 [
'/* insecure input */',
'foo: attr( title, url );' ],
318 [
'/* insecure input */',
'foo: attr( title url );' ],
326 public function testEscapeHtmlAllowEntities( $expected,
$html ) {
329 Sanitizer::escapeHtmlAllowEntities(
$html )
333 public static function provideEscapeHtmlAllowEntities() {
336 [
'a¡b',
'a¡b' ],
337 [
'foo'bar',
"foo'bar" ],
338 [
'<script>foo</script>',
'<script>foo</script>' ],
348 public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) {
350 Sanitizer::escapeIdReferenceList( $referenceList,
'noninitial' ),
351 Sanitizer::escapeId( $id1,
'noninitial' )
353 . Sanitizer::escapeId( $id2,
'noninitial' )
357 public static function provideEscapeIdReferenceList() {
360 [
'foo bar',
'foo',
'bar' ],
361 [
'#1 #2',
'#1',
'#2' ],
362 [
'+1 +2',
'+1',
'+2' ],