595c76de1a
This function was originally introduced to fix an XSS attack in Netscape 4, which never affected any other browsers, or later versions of Netscape. I'm willing to go out on a limb, and say that we've officially dropped security support for Netscape 4. Props dmsnell, desrosj. Fixes #33848. git-svn-id: https://develop.svn.wordpress.org/trunk@38785 602fd350-edb4-49c9-b593-d223f7449a82
682 lines
20 KiB
PHP
682 lines
20 KiB
PHP
<?php
|
|
/**
|
|
* Some simple test cases for KSES post content filtering
|
|
*
|
|
* @group formatting
|
|
* @group kses
|
|
*/
|
|
class Tests_Kses extends WP_UnitTestCase {
|
|
|
|
/**
|
|
* @ticket 20210
|
|
*/
|
|
function test_wp_filter_post_kses_address() {
|
|
global $allowedposttags;
|
|
|
|
$attributes = array(
|
|
'class' => 'classname',
|
|
'id' => 'id',
|
|
'style' => 'color: red;',
|
|
'style' => 'color: red',
|
|
'style' => 'color: red; text-align:center',
|
|
'style' => 'color: red; text-align:center;',
|
|
'title' => 'title',
|
|
);
|
|
|
|
foreach ( $attributes as $name => $value ) {
|
|
$string = "<address $name='$value'>1 WordPress Avenue, The Internet.</address>";
|
|
$expect_string = "<address $name='" . str_replace( '; ', ';', trim( $value, ';' ) ) . "'>1 WordPress Avenue, The Internet.</address>";
|
|
$this->assertEquals( $expect_string, wp_kses( $string, $allowedposttags ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ticket 20210
|
|
*/
|
|
function test_wp_filter_post_kses_a() {
|
|
global $allowedposttags;
|
|
|
|
$attributes = array(
|
|
'class' => 'classname',
|
|
'id' => 'id',
|
|
'style' => 'color: red;',
|
|
'title' => 'title',
|
|
'href' => 'http://example.com',
|
|
'rel' => 'related',
|
|
'rev' => 'revision',
|
|
'name' => 'name',
|
|
'target' => '_blank',
|
|
);
|
|
|
|
foreach ( $attributes as $name => $value ) {
|
|
$string = "<a $name='$value'>I link this</a>";
|
|
$expect_string = "<a $name='" . trim( $value, ';' ) . "'>I link this</a>";
|
|
$this->assertEquals( $expect_string, wp_kses( $string, $allowedposttags ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ticket 20210
|
|
*/
|
|
function test_wp_filter_post_kses_abbr() {
|
|
global $allowedposttags;
|
|
|
|
$attributes = array(
|
|
'class' => 'classname',
|
|
'id' => 'id',
|
|
'style' => 'color: red;',
|
|
'title' => 'title',
|
|
);
|
|
|
|
foreach ( $attributes as $name => $value ) {
|
|
$string = "<abbr $name='$value'>WP</abbr>";
|
|
$expect_string = "<abbr $name='" . trim( $value, ';' ) . "'>WP</abbr>";
|
|
$this->assertEquals( $expect_string, wp_kses( $string, $allowedposttags ) );
|
|
}
|
|
}
|
|
|
|
function test_feed_links() {
|
|
global $allowedposttags;
|
|
|
|
$content = <<<EOF
|
|
<a href="feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:javascript:feed:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="javascript:feed:alert(1)">CLICK ME</a>
|
|
<a href="javascript:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:feed:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:feed:feed:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:javascript:feed:javascript:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:javascript:feed:javascript:feed:javascript:feed:javascript:feed:javascript:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:feed:http:alert(1)">CLICK ME</a>
|
|
EOF;
|
|
|
|
$expected = <<<EOF
|
|
<a href="feed:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:alert(1)">CLICK ME</a>
|
|
<a href="feed:feed:alert(1)">CLICK ME</a>
|
|
<a href="feed:alert(1)">CLICK ME</a>
|
|
<a href="feed:alert(1)">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
<a href="">CLICK ME</a>
|
|
EOF;
|
|
|
|
$this->assertEquals( $expected, wp_kses( $content, $allowedposttags ) );
|
|
}
|
|
|
|
function test_wp_kses_bad_protocol() {
|
|
$bad = array(
|
|
'dummy:alert(1)',
|
|
'javascript:alert(1)',
|
|
'JaVaScRiPt:alert(1)',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert(1);',
|
|
'javascript:alert('XSS')',
|
|
'jav ascript:alert(1);',
|
|
'jav	ascript:alert(1);',
|
|
'jav
ascript:alert(1);',
|
|
'jav
ascript:alert(1);',
|
|
'  javascript:alert(1);',
|
|
'javascript:javascript:alert(1);',
|
|
'javascript:javascript:alert(1);',
|
|
'javascript:javascript:alert(1);',
|
|
'javascript:javascript:alert(1);',
|
|
'javascript:javascript:alert(1);',
|
|
'javascript:alert(1)//?:',
|
|
'feed:javascript:alert(1)',
|
|
'feed:javascript:feed:javascript:feed:javascript:alert(1)',
|
|
);
|
|
foreach ( $bad as $k => $x ) {
|
|
$result = wp_kses_bad_protocol( wp_kses_normalize_entities( $x ), wp_allowed_protocols() );
|
|
if ( ! empty( $result ) && $result != 'alert(1);' && $result != 'alert(1)' ) {
|
|
switch ( $k ) {
|
|
case 6: $this->assertEquals( 'javascript&#0000058alert(1);', $result ); break;
|
|
case 12:
|
|
$this->assertEquals( str_replace( '&', '&', $x ), $result );
|
|
break;
|
|
case 22: $this->assertEquals( 'javascript&#0000058alert(1);', $result ); break;
|
|
case 23: $this->assertEquals( 'javascript&#0000058alert(1)//?:', $result ); break;
|
|
case 24: $this->assertEquals( 'feed:alert(1)', $result ); break;
|
|
default: $this->fail( "wp_kses_bad_protocol failed on $x. Result: $result" );
|
|
}
|
|
}
|
|
}
|
|
|
|
$safe = array(
|
|
'dummy:alert(1)',
|
|
'HTTP://example.org/',
|
|
'http://example.org/',
|
|
'http://example.org/',
|
|
'http://example.org/',
|
|
'https://example.org',
|
|
'http://example.org/wp-admin/post.php?post=2&action=edit',
|
|
'http://example.org/index.php?test='blah'',
|
|
);
|
|
foreach ( $safe as $x ) {
|
|
$result = wp_kses_bad_protocol( wp_kses_normalize_entities( $x ), array( 'http', 'https', 'dummy' ) );
|
|
if ( $result != $x && $result != 'http://example.org/' )
|
|
$this->fail( "wp_kses_bad_protocol incorrectly blocked $x" );
|
|
}
|
|
}
|
|
|
|
public function test_hackers_attacks() {
|
|
$xss = simplexml_load_file( DIR_TESTDATA . '/formatting/xssAttacks.xml' );
|
|
foreach ( $xss->attack as $attack ) {
|
|
if ( in_array( $attack->name, array( 'IMG Embedded commands 2', 'US-ASCII encoding', 'OBJECT w/Flash 2', 'Character Encoding Example' ) ) )
|
|
continue;
|
|
|
|
$code = (string) $attack->code;
|
|
|
|
if ( $code == 'See Below' )
|
|
continue;
|
|
|
|
if ( substr( $code, 0, 4 ) == 'perl' ) {
|
|
$pos = strpos( $code, '"' ) + 1;
|
|
$code = substr( $code, $pos, strrpos($code, '"') - $pos );
|
|
$code = str_replace( '\0', "\0", $code );
|
|
}
|
|
|
|
$result = trim( wp_kses_data( $code ) );
|
|
|
|
if ( $result == '' || $result == 'XSS' || $result == 'alert("XSS");' || $result == "alert('XSS');" )
|
|
continue;
|
|
|
|
switch ( $attack->name ) {
|
|
case 'XSS Locator':
|
|
$this->assertEquals('\';alert(String.fromCharCode(88,83,83))//\\\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\\";alert(String.fromCharCode(88,83,83))//-->">\'>alert(String.fromCharCode(88,83,83))=&{}', $result);
|
|
break;
|
|
case 'XSS Quick Test':
|
|
$this->assertEquals('\'\';!--"=&{()}', $result);
|
|
break;
|
|
case 'SCRIPT w/Alert()':
|
|
$this->assertEquals( "alert('XSS')", $result );
|
|
break;
|
|
case 'SCRIPT w/Char Code':
|
|
$this->assertEquals('alert(String.fromCharCode(88,83,83))', $result);
|
|
break;
|
|
case 'IMG STYLE w/expression':
|
|
$this->assertEquals('exp/*', $result);
|
|
break;
|
|
case 'List-style-image':
|
|
$this->assertEquals('li {list-style-image: url("javascript:alert(\'XSS\')");}XSS', $result);
|
|
break;
|
|
case 'STYLE':
|
|
$this->assertEquals( "alert('XSS');", $result);
|
|
break;
|
|
case 'STYLE w/background-image':
|
|
$this->assertEquals('.XSS{background-image:url("javascript:alert(\'XSS\')");}<A></A>', $result);
|
|
break;
|
|
case 'STYLE w/background':
|
|
$this->assertEquals('BODY{background:url("javascript:alert(\'XSS\')")}', $result);
|
|
break;
|
|
case 'Remote Stylesheet 2':
|
|
$this->assertEquals( "@import'http://ha.ckers.org/xss.css';", $result );
|
|
break;
|
|
case 'Remote Stylesheet 3':
|
|
$this->assertEquals( '<META HTTP-EQUIV="Link" Content="; REL=stylesheet">', $result );
|
|
break;
|
|
case 'Remote Stylesheet 4':
|
|
$this->assertEquals('BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}', $result);
|
|
break;
|
|
case 'XML data island w/CDATA':
|
|
$this->assertEquals( "<![CDATA[]]>", $result );
|
|
break;
|
|
case 'XML data island w/comment':
|
|
$this->assertEquals( "<I><B><IMG SRC="javas<!-- -->cript:alert('XSS')\"></B></I>", $result );
|
|
break;
|
|
case 'XML HTML+TIME':
|
|
$this->assertEquals( '<t:set attributeName="innerHTML" to="XSSalert(\'XSS\')">', $result );
|
|
break;
|
|
case 'Commented-out Block':
|
|
$this->assertEquals( "<!--[if gte IE 4]>-->\nalert('XSS');", $result );
|
|
break;
|
|
case 'Cookie Manipulation':
|
|
$this->assertEquals( '<META HTTP-EQUIV="Set-Cookie" Content="USERID=alert(\'XSS\')">', $result );
|
|
break;
|
|
case 'SSI':
|
|
$this->assertEquals( '<!--#exec cmd="/bin/echo '<!--#exec cmd="/bin/echo \'=http://ha.ckers.org/xss.js>\'"-->', $result );
|
|
break;
|
|
case 'PHP':
|
|
$this->assertEquals( '<? echo('alert("XSS")\'); ?>', $result );
|
|
break;
|
|
case 'UTF-7 Encoding':
|
|
$this->assertEquals( '+ADw-SCRIPT+AD4-alert(\'XSS\');+ADw-/SCRIPT+AD4-', $result );
|
|
break;
|
|
case 'Escaping JavaScript escapes':
|
|
$this->assertEquals('\";alert(\'XSS\');//', $result);
|
|
break;
|
|
case 'STYLE w/broken up JavaScript':
|
|
$this->assertEquals( '@im\port\'\ja\vasc\ript:alert("XSS")\';', $result );
|
|
break;
|
|
case 'Null Chars 2':
|
|
$this->assertEquals( '&alert("XSS")', $result );
|
|
break;
|
|
case 'No Closing Script Tag':
|
|
$this->assertEquals( '<SCRIPT SRC=http://ha.ckers.org/xss.js', $result );
|
|
break;
|
|
case 'Half-Open HTML/JavaScript':
|
|
$this->assertEquals( '<IMG SRC="javascript:alert('XSS')"', $result );
|
|
break;
|
|
case 'Double open angle brackets':
|
|
$this->assertEquals( '<IFRAME SRC=http://ha.ckers.org/scriptlet.html <', $result );
|
|
break;
|
|
case 'Extraneous Open Brackets':
|
|
$this->assertEquals( '<alert("XSS");//<', $result );
|
|
break;
|
|
case 'Malformed IMG Tags':
|
|
$this->assertEquals('alert("XSS")">', $result);
|
|
break;
|
|
case 'No Quotes/Semicolons':
|
|
$this->assertEquals( "a=/XSS/\nalert(a.source)", $result );
|
|
break;
|
|
case 'Evade Regex Filter 1':
|
|
$this->assertEquals( '" SRC="http://ha.ckers.org/xss.js">', $result );
|
|
break;
|
|
case 'Evade Regex Filter 4':
|
|
$this->assertEquals( '\'" SRC="http://ha.ckers.org/xss.js">', $result );
|
|
break;
|
|
case 'Evade Regex Filter 5':
|
|
$this->assertEquals( '` SRC="http://ha.ckers.org/xss.js">', $result );
|
|
break;
|
|
case 'Filter Evasion 1':
|
|
$this->assertEquals( 'document.write("<SCRI");PT SRC="http://ha.ckers.org/xss.js">', $result );
|
|
break;
|
|
case 'Filter Evasion 2':
|
|
$this->assertEquals( '\'>" SRC="http://ha.ckers.org/xss.js">', $result );
|
|
break;
|
|
default:
|
|
$this->fail( 'KSES failed on ' . $attack->name . ': ' . $result );
|
|
}
|
|
}
|
|
}
|
|
|
|
function _wp_kses_allowed_html_filter( $html, $context ) {
|
|
if ( 'post' == $context )
|
|
return array( 'a' => array( 'href' => true ) );
|
|
else
|
|
return array( 'a' => array( 'href' => false ) );
|
|
}
|
|
|
|
/**
|
|
* @ticket 20210
|
|
*/
|
|
public function test_wp_kses_allowed_html() {
|
|
global $allowedposttags, $allowedtags, $allowedentitynames;
|
|
|
|
$this->assertEquals( $allowedposttags, wp_kses_allowed_html( 'post' ) );
|
|
|
|
$tags = wp_kses_allowed_html( 'post' ) ;
|
|
|
|
foreach ( $tags as $tag ) {
|
|
$this->assertTrue( $tag['class'] );
|
|
$this->assertTrue( $tag['id'] );
|
|
$this->assertTrue( $tag['style'] );
|
|
$this->assertTrue( $tag['title'] );
|
|
}
|
|
|
|
$this->assertEquals( $allowedtags, wp_kses_allowed_html( 'data' ) );
|
|
$this->assertEquals( $allowedtags, wp_kses_allowed_html( '' ) );
|
|
$this->assertEquals( $allowedtags, wp_kses_allowed_html() );
|
|
|
|
$tags = wp_kses_allowed_html( 'user_description' );
|
|
$this->assertTrue( $tags['a']['rel'] );
|
|
|
|
$tags = wp_kses_allowed_html();
|
|
$this->assertFalse( isset( $tags['a']['rel'] ) );
|
|
|
|
$this->assertEquals( array(), wp_kses_allowed_html( 'strip' ) );
|
|
|
|
$custom_tags = array(
|
|
'a' => array(
|
|
'href' => true,
|
|
'rel' => true,
|
|
'rev' => true,
|
|
'name' => true,
|
|
'target' => true,
|
|
),
|
|
);
|
|
|
|
$this->assertEquals( $custom_tags, wp_kses_allowed_html( $custom_tags ) );
|
|
|
|
add_filter( 'wp_kses_allowed_html', array( $this, '_wp_kses_allowed_html_filter' ), 10, 2 );
|
|
|
|
$this->assertEquals( array( 'a' => array( 'href' => true ) ), wp_kses_allowed_html( 'post' ) );
|
|
$this->assertEquals( array( 'a' => array( 'href' => false ) ), wp_kses_allowed_html( 'data' ) );
|
|
|
|
remove_filter( 'wp_kses_allowed_html', array( $this, '_wp_kses_allowed_html_filter' ) );
|
|
$this->assertEquals( $allowedposttags, wp_kses_allowed_html( 'post' ) );
|
|
$this->assertEquals( $allowedtags, wp_kses_allowed_html( 'data' ) );
|
|
}
|
|
|
|
function test_hyphenated_tag() {
|
|
$string = "<hyphenated-tag attribute=\"value\" otherattribute=\"value2\">Alot of hyphens.</hyphenated-tag>";
|
|
$custom_tags = array(
|
|
'hyphenated-tag' => array(
|
|
'attribute' => true,
|
|
),
|
|
);
|
|
$expect_stripped_string = 'Alot of hyphens.';
|
|
|
|
$expect_valid_string = "<hyphenated-tag attribute=\"value\">Alot of hyphens.</hyphenated-tag>";
|
|
$this->assertEquals( $expect_stripped_string, wp_kses_post( $string ) );
|
|
$this->assertEquals( $expect_valid_string, wp_kses( $string, $custom_tags ) );
|
|
}
|
|
|
|
/**
|
|
* @ticket 26290
|
|
*/
|
|
public function test_wp_kses_normalize_entities() {
|
|
$this->assertEquals( '♠', wp_kses_normalize_entities( '♠' ) );
|
|
|
|
$this->assertEquals( '¹', wp_kses_normalize_entities( '¹' ) );
|
|
$this->assertEquals( '²', wp_kses_normalize_entities( '²' ) );
|
|
$this->assertEquals( '³', wp_kses_normalize_entities( '³' ) );
|
|
$this->assertEquals( '¼', wp_kses_normalize_entities( '¼' ) );
|
|
$this->assertEquals( '½', wp_kses_normalize_entities( '½' ) );
|
|
$this->assertEquals( '¾', wp_kses_normalize_entities( '¾' ) );
|
|
$this->assertEquals( '∴', wp_kses_normalize_entities( '∴' ) );
|
|
}
|
|
|
|
/**
|
|
* Test removal of invalid binary data for HTML.
|
|
*
|
|
* @ticket 28506
|
|
* @dataProvider data_ctrl_removal
|
|
*/
|
|
function test_ctrl_removal( $input, $output ) {
|
|
global $allowedposttags;
|
|
|
|
return $this->assertEquals( $output, wp_kses( $input, $allowedposttags ) );
|
|
}
|
|
|
|
function data_ctrl_removal() {
|
|
return array(
|
|
array(
|
|
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\X1C\x1D\x1E\x1F",
|
|
'',
|
|
),
|
|
array(
|
|
"\x00h\x01e\x02l\x03l\x04o\x05 \x06w\x07o\x08r\x0Bl\x0Cd\x0E.\x0F \x10W\x11O\x12R\x13D\x14P\x15R\x16E\x17S\x18S\x19 \x1AK\x1BS\X1CE\x1DS\x1E.\x1F/",
|
|
'hello world. WORDPRESS KSES./',
|
|
),
|
|
array(
|
|
"\x1F\x1E\x1D\x1C\x1B\x1A\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10\x0F\x0E\x0C\x0B\x08\x07\x06\x05\x04\X03\x02\x01\x00",
|
|
'',
|
|
),
|
|
array(
|
|
"\x1Fh\x1Ee\x1Dl\x1Cl\x1Bo\x1A \x19w\x18o\x17r\x16l\x15d\x14.\x13 \x12W\x11O\x10R\x0FD\x0EP\x0CR\x0BE\x08S\x07S\x06 \x05K\x04S\X03E\x02S\x01.\x00/",
|
|
'hello world. WORDPRESS KSES./',
|
|
),
|
|
array(
|
|
"\t\r\n word \n\r\t",
|
|
"\t\r\n word \n\r\t",
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test removal of '\0' strings.
|
|
*
|
|
* @ticket 28699
|
|
* @dataProvider data_slash_zero_removal
|
|
*/
|
|
function test_slash_zero_removal( $input, $output ) {
|
|
global $allowedposttags;
|
|
|
|
return $this->assertEquals( $output, wp_kses( $input, $allowedposttags ) );
|
|
}
|
|
|
|
function data_slash_zero_removal() {
|
|
return array(
|
|
array(
|
|
'This \\0 should be no big deal.',
|
|
'This \\0 should be no big deal.',
|
|
),
|
|
array(
|
|
'<div>This \\0 should be no big deal.</div>',
|
|
'<div>This \\0 should be no big deal.</div>',
|
|
),
|
|
array(
|
|
'<div align="\\0left">This should be no big deal.</div>',
|
|
'<div align="\\0left">This should be no big deal.</div>',
|
|
),
|
|
array(
|
|
'This <div style="float:\\0left"> is more of a concern.',
|
|
'This <div style="float:left"> is more of a concern.',
|
|
),
|
|
array(
|
|
'This <div style="float:\\0\\0left"> is more of a concern.',
|
|
'This <div style="float:left"> is more of a concern.',
|
|
),
|
|
array(
|
|
'This <div style="float:\\\\00left"> is more of a concern.',
|
|
'This <div style="float:left"> is more of a concern.',
|
|
),
|
|
array(
|
|
'This <div style="float:\\\\\\\\0000left"> is more of a concern.',
|
|
'This <div style="float:left"> is more of a concern.',
|
|
),
|
|
array(
|
|
'This <div style="float:\\0000left"> is more of a concern.',
|
|
'This <div style="float:left"> is more of a concern.',
|
|
),
|
|
array(
|
|
'<style type="text/css">div {background-image:\\0}</style>',
|
|
'div {background-image:\\0}',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test new function wp_kses_hair_parse().
|
|
*
|
|
* @dataProvider data_hair_parse
|
|
*/
|
|
function test_hair_parse( $input, $output ) {
|
|
return $this->assertEquals( $output, wp_kses_hair_parse( $input ) );
|
|
}
|
|
|
|
function data_hair_parse() {
|
|
return array(
|
|
array(
|
|
'title="hello" href="#" id="my_id" ',
|
|
array( 'title="hello" ', 'href="#" ', 'id="my_id" ' ),
|
|
),
|
|
array(
|
|
'[shortcode attr="value"] href="http://www.google.com/"title="moo"disabled',
|
|
array( '[shortcode attr="value"] ', 'href="http://www.google.com/"', 'title="moo"', 'disabled' ),
|
|
),
|
|
array(
|
|
'',
|
|
array(),
|
|
),
|
|
array(
|
|
'a',
|
|
array( 'a' ),
|
|
),
|
|
array(
|
|
'title="hello"disabled href=# id=\'my_id\'',
|
|
array( 'title="hello"', 'disabled ', 'href=# ', "id='my_id'" ),
|
|
),
|
|
array(
|
|
' ', // Calling function is expected to strip leading whitespace.
|
|
false,
|
|
),
|
|
array(
|
|
'abcd=abcd"abcd"',
|
|
false,
|
|
),
|
|
array(
|
|
"array[1]='z'z'z'z",
|
|
false,
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test new function wp_kses_attr_parse().
|
|
*
|
|
* @dataProvider data_attr_parse
|
|
*/
|
|
function test_attr_parse( $input, $output ) {
|
|
return $this->assertEquals( $output, wp_kses_attr_parse( $input ) );
|
|
}
|
|
|
|
function data_attr_parse() {
|
|
return array(
|
|
array(
|
|
'<a title="hello" href="#" id="my_id" >',
|
|
array( '<a ', 'title="hello" ', 'href="#" ', 'id="my_id" ', '>' ),
|
|
),
|
|
array(
|
|
'<a [shortcode attr="value"] href="http://www.google.com/"title="moo"disabled>',
|
|
array( '<a ', '[shortcode attr="value"] ', 'href="http://www.google.com/"', 'title="moo"', 'disabled', '>' ),
|
|
),
|
|
array(
|
|
'',
|
|
false,
|
|
),
|
|
array(
|
|
'a',
|
|
false,
|
|
),
|
|
array(
|
|
'<a>',
|
|
array( '<a', '>' ),
|
|
),
|
|
array(
|
|
'<a%%&&**>',
|
|
false,
|
|
),
|
|
array(
|
|
'<a title="hello"disabled href=# id=\'my_id\'>',
|
|
array( '<a ', 'title="hello"', 'disabled ', 'href=# ', "id='my_id'", ">" ),
|
|
),
|
|
array(
|
|
'<a >',
|
|
array( '<a ', '>' ),
|
|
),
|
|
array(
|
|
'<a abcd=abcd"abcd">',
|
|
false,
|
|
),
|
|
array(
|
|
"<a array[1]='z'z'z'z>",
|
|
false,
|
|
),
|
|
array(
|
|
'<img title="hello" src="#" id="my_id" />',
|
|
array( '<img ', 'title="hello" ', 'src="#" ', 'id="my_id"', ' />' ),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test new function wp_kses_one_attr().
|
|
*
|
|
* @dataProvider data_one_attr
|
|
*/
|
|
function test_one_attr( $element, $input, $output ) {
|
|
return $this->assertEquals( $output, wp_kses_one_attr( $input, $element ) );
|
|
}
|
|
|
|
function data_one_attr() {
|
|
return array(
|
|
array(
|
|
'a',
|
|
' title="hello" ',
|
|
' title="hello" ',
|
|
),
|
|
array(
|
|
'a',
|
|
'title = "hello"',
|
|
'title="hello"',
|
|
),
|
|
array(
|
|
'a',
|
|
"title='hello'",
|
|
"title='hello'",
|
|
),
|
|
array(
|
|
'a',
|
|
'title=hello',
|
|
'title="hello"',
|
|
),
|
|
array(
|
|
'a',
|
|
'href="javascript:alert(1)"',
|
|
'href="alert(1)"',
|
|
),
|
|
array(
|
|
'a',
|
|
'style ="style "',
|
|
'style="style"',
|
|
),
|
|
array(
|
|
'a',
|
|
'style="style "',
|
|
'style="style"',
|
|
),
|
|
array(
|
|
'a',
|
|
'style ="style ="',
|
|
'',
|
|
),
|
|
array(
|
|
'img',
|
|
'src="mypic.jpg"',
|
|
'src="mypic.jpg"',
|
|
),
|
|
array(
|
|
'img',
|
|
'onerror=alert(1)',
|
|
'',
|
|
),
|
|
array(
|
|
'img',
|
|
'title=>',
|
|
'title=">"',
|
|
),
|
|
array(
|
|
'img',
|
|
'title="&garbage";"',
|
|
'title="&garbage";"',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @ticket 34063
|
|
*/
|
|
function test_bdo() {
|
|
global $allowedposttags;
|
|
|
|
$input = '<p>This is <bdo dir="rtl">a BDO tag</bdo>. Weird, <bdo dir="ltr">right?</bdo></p>';
|
|
|
|
$this->assertEquals( $input, wp_kses( $input, $allowedposttags ) );
|
|
}
|
|
|
|
/**
|
|
* @ticket 35079
|
|
*/
|
|
function test_ol_reversed() {
|
|
global $allowedposttags;
|
|
|
|
$input = '<ol reversed="reversed"><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol>';
|
|
|
|
$this->assertEquals( $input, wp_kses( $input, $allowedposttags ) );
|
|
}
|
|
}
|