123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449 |
- <?php
- /**
- * Some simple test cases for KSES post content filtering
- *
- * @group formatting
- * @group kses
- */
- class Tests_Kses extends WP_UnitTestCase {
- /**
- * @dataProvider data_wp_filter_post_kses_address
- * @ticket 20210
- *
- * @param string $string Test string for kses.
- * @param string $expect_string Expected result after passing through kses.
- */
- function test_wp_filter_post_kses_address( $string, $expect_string ) {
- global $allowedposttags;
- $this->assertSame( $expect_string, wp_kses( $string, $allowedposttags ) );
- }
- /**
- * Data provider for test_wp_filter_post_kses_address.
- *
- * @return array[] Arguments {
- * @type string $string Test string for kses.
- * @type string $expect_string Expected result after passing through kses.
- * }
- */
- function data_wp_filter_post_kses_address() {
- $attributes = array(
- 'class' => 'classname',
- 'id' => 'id',
- 'style' => array(
- 'color: red;',
- 'color: red',
- 'color: red; text-align:center',
- 'color: red; text-align:center;',
- ),
- 'title' => 'title',
- );
- $data = array();
- foreach ( $attributes as $name => $values ) {
- foreach ( (array) $values as $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>";
- $data[] = array( $string, $expect_string );
- }
- }
- return $data;
- }
- /**
- * @dataProvider data_wp_filter_post_kses_a
- * @ticket 20210
- *
- * @param string $string Test string for kses.
- * @param string $expect_string Expected result after passing through kses.
- * @return void
- */
- function test_wp_filter_post_kses_a( $string, $expect_string ) {
- global $allowedposttags;
- $this->assertSame( $expect_string, wp_kses( $string, $allowedposttags ) );
- }
- /**
- * Data provider for test_wp_filter_post_kses_a.
- *
- * @return array[] Arguments {
- * @type string $string Test string for kses.
- * @type string $expect_string Expected result after passing through kses.
- * }
- */
- function data_wp_filter_post_kses_a() {
- $attributes = array(
- 'class' => 'classname',
- 'id' => 'id',
- 'style' => 'color: red;',
- 'title' => 'title',
- 'href' => 'http://example.com',
- 'rel' => 'related',
- 'rev' => 'revision',
- 'name' => 'name',
- 'target' => '_blank',
- 'download' => '',
- );
- $data = array();
- foreach ( $attributes as $name => $value ) {
- if ( $value ) {
- $attr = "$name='$value'";
- $expected_attr = "$name='" . trim( $value, ';' ) . "'";
- } else {
- $attr = $name;
- $expected_attr = $name;
- }
- $string = "<a $attr>I link this</a>";
- $expect_string = "<a $expected_attr>I link this</a>";
- $data[] = array( $string, $expect_string );
- }
- return $data;
- }
- /**
- * Test video tag.
- *
- * @ticket 50167
- * @ticket 29826
- * @dataProvider data_wp_kses_video
- *
- * @param string $source Source HTML.
- * @param string $context Context to use for parsing source.
- * @param string $expected Expected output following KSES parsing.
- */
- function test_wp_kses_video( $source, $context, $expected ) {
- $actual = wp_kses( $source, $context );
- $this->assertSame( $expected, $actual );
- }
- /**
- * Data provider for test_wp_kses_video
- *
- * @return array[] Array containing test data {
- * @type string $source Source HTML.
- * @type string $context Context to use for parsing source.
- * @type string $expected Expected output following KSES parsing.
- * }
- */
- function data_wp_kses_video() {
- return array(
- // Set 0: Valid post object params in post context.
- array(
- '<video src="movie.mov" autoplay controls height=9 loop muted poster="still.gif" playsinline preload width=16 />',
- 'post',
- '<video src="movie.mov" autoplay controls height="9" loop muted poster="still.gif" playsinline preload width="16" />',
- ),
- // Set 1: Valid post object params in data context.
- array(
- '<video src="movie.mov" autoplay controls height=9 loop muted poster="still.gif" playsinline preload width=16 />',
- 'data',
- '',
- ),
- // Set 2: Disallowed urls in post context.
- array(
- '<video src="bad://w.org/movie.mov" poster="bad://w.org/movie.jpg" />',
- 'post',
- '<video src="//w.org/movie.mov" poster="//w.org/movie.jpg" />',
- ),
- // Set 3: Disallowed attributes in post context.
- array(
- '<video onload="alert(1);" src="https://videos.files.wordpress.com/DZEMDKxc/video-0f9c363010.mp4" />',
- 'post',
- '<video src="https://videos.files.wordpress.com/DZEMDKxc/video-0f9c363010.mp4" />',
- ),
- );
- }
- /**
- * @dataProvider data_wp_filter_post_kses_abbr
- * @ticket 20210
- *
- * @param string $string Test string for kses.
- * @param string $expect_string Expected result after passing through kses.
- * @return void
- */
- function test_wp_filter_post_kses_abbr( $string, $expect_string ) {
- global $allowedposttags;
- $this->assertSame( $expect_string, wp_kses( $string, $allowedposttags ) );
- }
- /**
- * Data provider for data_wp_filter_post_kses_abbr.
- *
- * @return array[] Arguments {
- * @type string $string Test string for kses.
- * @type string $expect_string Expected result after passing through kses.
- * }
- */
- function data_wp_filter_post_kses_abbr() {
- $attributes = array(
- 'class' => 'classname',
- 'id' => 'id',
- 'style' => 'color: red;',
- 'title' => 'title',
- );
- $data = array();
- foreach ( $attributes as $name => $value ) {
- $string = "<abbr $name='$value'>WP</abbr>";
- $expect_string = "<abbr $name='" . trim( $value, ';' ) . "'>WP</abbr>";
- $data[] = array( $string, $expect_string );
- }
- return $data;
- }
- 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->assertSame( $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)',
- 'javascript:alert(1)',
- 'javascript:x=1;alert(1)',
- );
- foreach ( $bad as $k => $x ) {
- $result = wp_kses_bad_protocol( wp_kses_normalize_entities( $x ), wp_allowed_protocols() );
- if ( ! empty( $result ) && 'alert(1);' !== $result && 'alert(1)' !== $result ) {
- switch ( $k ) {
- case 6:
- $this->assertSame( 'javascript&#0000058alert(1);', $result );
- break;
- case 12:
- $this->assertSame( str_replace( '&', '&', $x ), $result );
- break;
- case 22:
- $this->assertSame( 'javascript&#0000058alert(1);', $result );
- break;
- case 23:
- $this->assertSame( 'javascript&#0000058alert(1)//?:', $result );
- break;
- case 24:
- $this->assertSame( 'feed:alert(1)', $result );
- break;
- case 26:
- $this->assertSame( 'javascript&#58alert(1)', $result );
- break;
- case 27:
- $this->assertSame( 'javascript&#x3ax=1;alert(1)', $result );
- break;
- default:
- $this->fail( "wp_kses_bad_protocol failed on $k, $x. Result: $result" );
- }
- }
- }
- $bad_not_normalized = array(
- 'dummy:alert(1)',
- 'javascript:alert(1)',
- 'javascript&CoLon;alert(1)',
- 'javascript&COLON;alert(1);',
- 'javascript:alert(1);',
- 'javascript:alert(1);',
- 'javascript:alert(1);',
- 'jav ascript&COLON;alert(1);',
- 'javascript:javascript:alert(1);',
- 'javascript:javascript:alert(1);',
- 'javascript:javascript:alert(1);',
- 'javascript:javascript:alert(1);',
- 'javascript:alert(1)',
- );
- foreach ( $bad_not_normalized as $k => $x ) {
- $result = wp_kses_bad_protocol( $x, wp_allowed_protocols() );
- if ( ! empty( $result ) && 'alert(1);' !== $result && 'alert(1)' !== $result ) {
- $this->fail( "wp_kses_bad_protocol failed on $k, $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 && 'http://example.org/' !== $result ) {
- $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( (string) $attack->name, array( 'IMG Embedded commands 2', 'US-ASCII encoding', 'OBJECT w/Flash 2', 'Character Encoding Example' ), true ) ) {
- continue;
- }
- $code = (string) $attack->code;
- if ( 'See Below' === $code ) {
- 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 ( in_array( $result, array( '', 'XSS', 'alert("XSS");', "alert('XSS');" ), true ) ) {
- continue;
- }
- switch ( $attack->name ) {
- case 'XSS Locator':
- $this->assertSame( '\';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->assertSame( '\'\';!--"=&{()}', $result );
- break;
- case 'SCRIPT w/Alert()':
- $this->assertSame( "alert('XSS')", $result );
- break;
- case 'SCRIPT w/Char Code':
- $this->assertSame( 'alert(String.fromCharCode(88,83,83))', $result );
- break;
- case 'IMG STYLE w/expression':
- $this->assertSame( 'exp/*', $result );
- break;
- case 'List-style-image':
- $this->assertSame( 'li {list-style-image: url("javascript:alert(\'XSS\')");}XSS', $result );
- break;
- case 'STYLE':
- $this->assertSame( "alert('XSS');", $result );
- break;
- case 'STYLE w/background-image':
- $this->assertSame( '.XSS{background-image:url("javascript:alert(\'XSS\')");}<A></A>', $result );
- break;
- case 'STYLE w/background':
- $this->assertSame( 'BODY{background:url("javascript:alert(\'XSS\')")}', $result );
- break;
- case 'Remote Stylesheet 2':
- $this->assertSame( "@import'http://ha.ckers.org/xss.css';", $result );
- break;
- case 'Remote Stylesheet 3':
- $this->assertSame( '<META HTTP-EQUIV="Link" Content="; REL=stylesheet">', $result );
- break;
- case 'Remote Stylesheet 4':
- $this->assertSame( 'BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}', $result );
- break;
- case 'XML data island w/CDATA':
- $this->assertSame( '<![CDATA[]]>', $result );
- break;
- case 'XML data island w/comment':
- $this->assertSame( "<I><B><IMG SRC="javas<!-- -->cript:alert('XSS')\"></B></I>", $result );
- break;
- case 'XML HTML+TIME':
- $this->assertSame( '<t:set attributeName="innerHTML" to="XSSalert(\'XSS\')">', $result );
- break;
- case 'Commented-out Block':
- $this->assertSame( "<!--[if gte IE 4]>-->\nalert('XSS');", $result );
- break;
- case 'Cookie Manipulation':
- $this->assertSame( '<META HTTP-EQUIV="Set-Cookie" Content="USERID=alert(\'XSS\')">', $result );
- break;
- case 'SSI':
- $this->assertSame( '<!--#exec cmd="/bin/echo '<!--#exec cmd="/bin/echo \'=http://ha.ckers.org/xss.js>\'"-->', $result );
- break;
- case 'PHP':
- $this->assertSame( '<? echo('alert("XSS")\'); ?>', $result );
- break;
- case 'UTF-7 Encoding':
- $this->assertSame( '+ADw-SCRIPT+AD4-alert(\'XSS\');+ADw-/SCRIPT+AD4-', $result );
- break;
- case 'Escaping JavaScript escapes':
- $this->assertSame( '\";alert(\'XSS\');//', $result );
- break;
- case 'STYLE w/broken up JavaScript':
- $this->assertSame( '@im\port\'\ja\vasc\ript:alert("XSS")\';', $result );
- break;
- case 'Null Chars 2':
- $this->assertSame( '&alert("XSS")', $result );
- break;
- case 'No Closing Script Tag':
- $this->assertSame( '<SCRIPT SRC=http://ha.ckers.org/xss.js', $result );
- break;
- case 'Half-Open HTML/JavaScript':
- $this->assertSame( '<IMG SRC="javascript:alert('XSS')"', $result );
- break;
- case 'Double open angle brackets':
- $this->assertSame( '<IFRAME SRC=http://ha.ckers.org/scriptlet.html <', $result );
- break;
- case 'Extraneous Open Brackets':
- $this->assertSame( '<alert("XSS");//<', $result );
- break;
- case 'Malformed IMG Tags':
- $this->assertSame( 'alert("XSS")">', $result );
- break;
- case 'No Quotes/Semicolons':
- $this->assertSame( "a=/XSS/\nalert(a.source)", $result );
- break;
- case 'Evade Regex Filter 1':
- $this->assertSame( '" SRC="http://ha.ckers.org/xss.js">', $result );
- break;
- case 'Evade Regex Filter 4':
- $this->assertSame( '\'" SRC="http://ha.ckers.org/xss.js">', $result );
- break;
- case 'Evade Regex Filter 5':
- $this->assertSame( '` SRC="http://ha.ckers.org/xss.js">', $result );
- break;
- case 'Filter Evasion 1':
- $this->assertSame( 'document.write("<SCRI");PT SRC="http://ha.ckers.org/xss.js">', $result );
- break;
- case 'Filter Evasion 2':
- $this->assertSame( '\'>" 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->assertSame( $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->assertSame( $allowedtags, wp_kses_allowed_html( 'data' ) );
- $this->assertSame( $allowedtags, wp_kses_allowed_html( '' ) );
- $this->assertSame( $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->assertSame( array(), wp_kses_allowed_html( 'strip' ) );
- $custom_tags = array(
- 'a' => array(
- 'href' => true,
- 'rel' => true,
- 'rev' => true,
- 'name' => true,
- 'target' => true,
- ),
- );
- $this->assertSame( $custom_tags, wp_kses_allowed_html( $custom_tags ) );
- add_filter( 'wp_kses_allowed_html', array( $this, '_wp_kses_allowed_html_filter' ), 10, 2 );
- $this->assertSame( array( 'a' => array( 'href' => true ) ), wp_kses_allowed_html( 'post' ) );
- $this->assertSame( array( 'a' => array( 'href' => false ) ), wp_kses_allowed_html( 'data' ) );
- remove_filter( 'wp_kses_allowed_html', array( $this, '_wp_kses_allowed_html_filter' ) );
- $this->assertSame( $allowedposttags, wp_kses_allowed_html( 'post' ) );
- $this->assertSame( $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->assertSame( $expect_stripped_string, wp_kses_post( $string ) );
- $this->assertSame( $expect_valid_string, wp_kses( $string, $custom_tags ) );
- }
- /**
- * @ticket 26290
- */
- public function test_wp_kses_normalize_entities() {
- $this->assertSame( '♠', wp_kses_normalize_entities( '♠' ) );
- $this->assertSame( '¹', wp_kses_normalize_entities( '¹' ) );
- $this->assertSame( '²', wp_kses_normalize_entities( '²' ) );
- $this->assertSame( '³', wp_kses_normalize_entities( '³' ) );
- $this->assertSame( '¼', wp_kses_normalize_entities( '¼' ) );
- $this->assertSame( '½', wp_kses_normalize_entities( '½' ) );
- $this->assertSame( '¾', wp_kses_normalize_entities( '¾' ) );
- $this->assertSame( '∴', 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->assertSame( $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->assertSame( $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->assertSame( $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,
- ),
- // Using a digit in attribute name should work.
- array(
- 'href="https://example.com/[shortcode attr=\'value\']" data-op3-timer-seconds="0"',
- array( 'href="https://example.com/[shortcode attr=\'value\']" ', 'data-op3-timer-seconds="0"' ),
- ),
- // Using an underscore in attribute name should work.
- array(
- 'href="https://example.com/[shortcode attr=\'value\']" data-op_timer-seconds="0"',
- array( 'href="https://example.com/[shortcode attr=\'value\']" ', 'data-op_timer-seconds="0"' ),
- ),
- // Using a period in attribute name should work.
- array(
- 'href="https://example.com/[shortcode attr=\'value\']" data-op.timer-seconds="0"',
- array( 'href="https://example.com/[shortcode attr=\'value\']" ', 'data-op.timer-seconds="0"' ),
- ),
- // Using a digit at the beginning of attribute name should return false.
- array(
- 'href="https://example.com/[shortcode attr=\'value\']" 3data-op-timer-seconds="0"',
- false,
- ),
- );
- }
- /**
- * Test new function wp_kses_attr_parse().
- *
- * @dataProvider data_attr_parse
- */
- function test_attr_parse( $input, $output ) {
- return $this->assertSame( $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->assertSame( $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',
- 'loading="lazy"',
- 'loading="lazy"',
- ),
- 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->assertSame( $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->assertSame( $input, wp_kses( $input, $allowedposttags ) );
- }
- /**
- * @ticket 40680
- */
- function test_wp_kses_attr_no_attributes_allowed_with_empty_array() {
- $element = 'foo';
- $attribute = 'title="foo" class="bar"';
- $this->assertSame( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => array() ), array() ) );
- }
- /**
- * @ticket 40680
- */
- function test_wp_kses_attr_no_attributes_allowed_with_true() {
- $element = 'foo';
- $attribute = 'title="foo" class="bar"';
- $this->assertSame( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => true ), array() ) );
- }
- /**
- * @ticket 40680
- */
- function test_wp_kses_attr_single_attribute_is_allowed() {
- $element = 'foo';
- $attribute = 'title="foo" class="bar"';
- $this->assertSame( "<{$element} title=\"foo\">", wp_kses_attr( $element, $attribute, array( 'foo' => array( 'title' => true ) ), array() ) );
- }
- /**
- * @ticket 43312
- */
- function test_wp_kses_attr_no_attributes_allowed_with_false() {
- $element = 'foo';
- $attribute = 'title="foo" class="bar"';
- $this->assertSame( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => false ), array() ) );
- }
- /**
- * Testing the safecss_filter_attr() function.
- *
- * @ticket 37248
- * @ticket 42729
- * @ticket 48376
- * @dataProvider data_test_safecss_filter_attr
- *
- * @param string $css A string of CSS rules.
- * @param string $expected Expected string of CSS rules.
- */
- public function test_safecss_filter_attr( $css, $expected ) {
- $this->assertSame( $expected, safecss_filter_attr( $css ) );
- }
- /**
- * Data Provider for test_safecss_filter_attr().
- *
- * @return array {
- * @type array {
- * @string string $css A string of CSS rules.
- * @string string $expected Expected string of CSS rules.
- * }
- * }
- */
- public function data_test_safecss_filter_attr() {
- return array(
- // Empty input, empty output.
- array(
- 'css' => '',
- 'expected' => '',
- ),
- // An arbitrary attribute name isn't allowed.
- array(
- 'css' => 'foo:bar',
- 'expected' => '',
- ),
- // A single attribute name, with a single value.
- array(
- 'css' => 'margin-top: 2px',
- 'expected' => 'margin-top: 2px',
- ),
- // Backslash \ isn't supported.
- array(
- 'css' => 'margin-top: \2px',
- 'expected' => '',
- ),
- // Curly bracket } isn't supported.
- array(
- 'css' => 'margin-bottom: 2px}',
- 'expected' => '',
- ),
- // A single attribute name, with a single text value.
- array(
- 'css' => 'text-transform: uppercase',
- 'expected' => 'text-transform: uppercase',
- ),
- // Only lowercase attribute names are supported.
- array(
- 'css' => 'Text-transform: capitalize',
- 'expected' => '',
- ),
- // Uppercase attribute values goes through.
- array(
- 'css' => 'text-transform: None',
- 'expected' => 'text-transform: None',
- ),
- // A single attribute, with multiple values.
- array(
- 'css' => 'font: bold 15px arial, sans-serif',
- 'expected' => 'font: bold 15px arial, sans-serif',
- ),
- // Multiple attributes, with single values.
- array(
- 'css' => 'font-weight: bold;font-size: 15px',
- 'expected' => 'font-weight: bold;font-size: 15px',
- ),
- // Multiple attributes, separated by a space.
- array(
- 'css' => 'font-weight: bold; font-size: 15px',
- 'expected' => 'font-weight: bold;font-size: 15px',
- ),
- // Multiple attributes, with multiple values.
- array(
- 'css' => 'margin: 10px 20px;padding: 5px 10px',
- 'expected' => 'margin: 10px 20px;padding: 5px 10px',
- ),
- // Parenthesis ( is supported for some attributes.
- array(
- 'css' => 'background: green url("foo.jpg") no-repeat fixed center',
- 'expected' => 'background: green url("foo.jpg") no-repeat fixed center',
- ),
- // Additional background attributes introduced in 5.3.
- array(
- 'css' => 'background-size: cover;background-size: 200px 100px;background-attachment: local, scroll;background-blend-mode: hard-light',
- 'expected' => 'background-size: cover;background-size: 200px 100px;background-attachment: local, scroll;background-blend-mode: hard-light',
- ),
- // `border-radius` attribute introduced in 5.3.
- array(
- 'css' => 'border-radius: 10% 30% 50% 70%;border-radius: 30px',
- 'expected' => 'border-radius: 10% 30% 50% 70%;border-radius: 30px',
- ),
- // `flex` and related attributes introduced in 5.3.
- array(
- 'css' => 'flex: 0 1 auto;flex-basis: 75%;flex-direction: row-reverse;flex-flow: row-reverse nowrap;flex-grow: 2;flex-shrink: 1',
- 'expected' => 'flex: 0 1 auto;flex-basis: 75%;flex-direction: row-reverse;flex-flow: row-reverse nowrap;flex-grow: 2;flex-shrink: 1',
- ),
- // `grid` and related attributes introduced in 5.3.
- array(
- 'css' => 'grid-template-columns: 1fr 60px;grid-auto-columns: min-content;grid-column-start: span 2;grid-column-end: -1;grid-column-gap: 10%;grid-gap: 10px 20px',
- 'expected' => 'grid-template-columns: 1fr 60px;grid-auto-columns: min-content;grid-column-start: span 2;grid-column-end: -1;grid-column-gap: 10%;grid-gap: 10px 20px',
- ),
- array(
- 'css' => 'grid-template-rows: 40px 4em 40px;grid-auto-rows: min-content;grid-row-start: -1;grid-row-end: 3;grid-row-gap: 1em',
- 'expected' => 'grid-template-rows: 40px 4em 40px;grid-auto-rows: min-content;grid-row-start: -1;grid-row-end: 3;grid-row-gap: 1em',
- ),
- // `grid` does not yet support functions or `\`.
- array(
- 'css' => 'grid-template-columns: repeat(2, 50px 1fr);grid-template: 1em / 20% 20px 1fr',
- 'expected' => '',
- ),
- // `flex` and `grid` alignments introduced in 5.3.
- array(
- 'css' => 'align-content: space-between;align-items: start;align-self: center;justify-items: center;justify-content: space-between;justify-self: end',
- 'expected' => 'align-content: space-between;align-items: start;align-self: center;justify-items: center;justify-content: space-between;justify-self: end',
- ),
- // `columns` and related attributes introduced in 5.3.
- array(
- 'css' => 'columns: 6rem auto;column-count: 4;column-fill: balance;column-gap: 9px;column-rule: thick inset blue;column-span: none;column-width: 120px',
- 'expected' => 'columns: 6rem auto;column-count: 4;column-fill: balance;column-gap: 9px;column-rule: thick inset blue;column-span: none;column-width: 120px',
- ),
- // Gradients introduced in 5.3.
- array(
- 'css' => 'background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
- 'expected' => 'background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
- ),
- array(
- 'css' => 'background: linear-gradient(135deg,rgba(6,147,227,1) ) (0%,rgb(155,81,224) 100%)',
- 'expected' => '',
- ),
- array(
- 'css' => 'background-image: linear-gradient(red,yellow);',
- 'expected' => 'background-image: linear-gradient(red,yellow)',
- ),
- array(
- 'css' => 'color: linear-gradient(red,yellow);',
- 'expected' => '',
- ),
- array(
- 'css' => 'background-image: linear-gradient(red,yellow); background: prop( red,yellow); width: 100px;',
- 'expected' => 'background-image: linear-gradient(red,yellow);width: 100px',
- ),
- array(
- 'css' => 'background: unknown-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
- 'expected' => '',
- ),
- array(
- 'css' => 'background: repeating-linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
- 'expected' => 'background: repeating-linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
- ),
- array(
- 'css' => 'width: 100px; height: 100px; background: linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%);',
- 'expected' => 'width: 100px;height: 100px;background: linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)',
- ),
- array(
- 'css' => 'background: radial-gradient(#ff0, red, yellow, green, rgba(6,147,227,1), rgb(155,81,224) 90%);',
- 'expected' => 'background: radial-gradient(#ff0, red, yellow, green, rgba(6,147,227,1), rgb(155,81,224) 90%)',
- ),
- array(
- 'css' => 'background: radial-gradient(#ff0, red, yellow, green, rgba(6,147,227,1), rgb(155,81,224) 90%);',
- 'expected' => 'background: radial-gradient(#ff0, red, yellow, green, rgba(6,147,227,1), rgb(155,81,224) 90%)',
- ),
- array(
- 'css' => 'background: conic-gradient(at 0% 30%, red 10%, yellow 30%, #1e90ff 50%)',
- 'expected' => 'background: conic-gradient(at 0% 30%, red 10%, yellow 30%, #1e90ff 50%)',
- ),
- // Expressions are not allowed.
- array(
- 'css' => 'height: expression( body.scrollTop + 50 + "px" )',
- 'expected' => '',
- ),
- // RGB color values are not allowed.
- array(
- 'css' => 'color: rgb( 100, 100, 100 )',
- 'expected' => '',
- ),
- // RGBA color values are not allowed.
- array(
- 'css' => 'color: rgb( 100, 100, 100, .4 )',
- 'expected' => '',
- ),
- );
- }
- /**
- * Data attributes are globally accepted.
- *
- * @ticket 33121
- */
- function test_wp_kses_attr_data_attribute_is_allowed() {
- $test = '<div data-foo="foo" data-bar="bar" datainvalid="gone" data--invaild="gone" data-also-invaild-="gone" data-two-hyphens="remains">Pens and pencils</div>';
- $expected = '<div data-foo="foo" data-bar="bar" data-two-hyphens="remains">Pens and pencils</div>';
- $this->assertSame( $expected, wp_kses_post( $test ) );
- }
- /**
- * Ensure wildcard attributes block unprefixed wildcard uses.
- *
- * @ticket 33121
- */
- function test_wildcard_requires_hyphen_after_prefix() {
- $allowed_html = array(
- 'div' => array(
- 'data-*' => true,
- 'on-*' => true,
- ),
- );
- $string = '<div datamelformed-prefix="gone" data="gone" data-="gone" onclick="alert(1)">Malformed attributes</div>';
- $expected = '<div>Malformed attributes</div>';
- $actual = wp_kses( $string, $allowed_html );
- $this->assertSame( $expected, $actual );
- }
- /**
- * Ensure wildcard allows two hyphen.
- *
- * @ticket 33121
- */
- function test_wildcard_allows_two_hyphens() {
- $allowed_html = array(
- 'div' => array(
- 'data-*' => true,
- ),
- );
- $string = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
- $expected = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
- $actual = wp_kses( $string, $allowed_html );
- $this->assertSame( $expected, $actual );
- }
- /**
- * Ensure wildcard attributes only support valid prefixes.
- *
- * @dataProvider data_wildcard_attribute_prefixes
- *
- * @ticket 33121
- */
- function test_wildcard_attribute_prefixes( $wildcard_attribute, $expected ) {
- $allowed_html = array(
- 'div' => array(
- $wildcard_attribute => true,
- ),
- );
- $name = str_replace( '*', strtolower( __FUNCTION__ ), $wildcard_attribute );
- $value = __FUNCTION__;
- $whole = "{$name}=\"{$value}\"";
- $actual = wp_kses_attr_check( $name, $value, $whole, 'n', 'div', $allowed_html );
- $this->assertSame( $expected, $actual );
- }
- /**
- * @return array Array of arguments for wildcard testing
- * [0] The prefix being tested.
- * [1] The outcome of `wp_kses_attr_check` for the prefix.
- */
- function data_wildcard_attribute_prefixes() {
- return array(
- // Ends correctly.
- array( 'data-*', true ),
- // Does not end with trialing `-`.
- array( 'data*', false ),
- // Multiple wildcards.
- array( 'd*ta-*', false ),
- array( 'data**', false ),
- );
- }
- /**
- * Test URL sanitization in the style tag.
- *
- * @dataProvider data_kses_style_attr_with_url
- *
- * @ticket 45067
- *
- * @param $input string The style attribute saved in the editor.
- * @param $expected string The sanitized style attribute.
- */
- function test_kses_style_attr_with_url( $input, $expected ) {
- $actual = safecss_filter_attr( $input );
- $this->assertSame( $expected, $actual );
- }
- /**
- * Data provider testing style attribute sanitization.
- *
- * @return array Nested array of input, expected pairs.
- */
- function data_kses_style_attr_with_url() {
- return array(
- /*
- * Valid use cases.
- */
- // Double quotes.
- array(
- 'background-image: url( "http://example.com/valid.gif" );',
- 'background-image: url( "http://example.com/valid.gif" )',
- ),
- // Single quotes.
- array(
- "background-image: url( 'http://example.com/valid.gif' );",
- "background-image: url( 'http://example.com/valid.gif' )",
- ),
- // No quotes.
- array(
- 'background-image: url( http://example.com/valid.gif );',
- 'background-image: url( http://example.com/valid.gif )',
- ),
- // Single quotes, extra spaces.
- array(
- "background-image: url( ' http://example.com/valid.gif ' );",
- "background-image: url( ' http://example.com/valid.gif ' )",
- ),
- // Line breaks, single quotes.
- array(
- "background-image: url(\n'http://example.com/valid.gif' );",
- "background-image: url('http://example.com/valid.gif' )",
- ),
- // Tabs not spaces, single quotes.
- array(
- "background-image: url(\t'http://example.com/valid.gif'\t\t);",
- "background-image: url('http://example.com/valid.gif')",
- ),
- // Single quotes, absolute path.
- array(
- "background: url('/valid.gif');",
- "background: url('/valid.gif')",
- ),
- // Single quotes, relative path.
- array(
- "background: url('../wp-content/uploads/2018/10/valid.gif');",
- "background: url('../wp-content/uploads/2018/10/valid.gif')",
- ),
- // Error check: valid property not containing a URL.
- array(
- 'background: red',
- 'background: red',
- ),
- /*
- * Invalid use cases.
- */
- // Attribute doesn't support URL properties.
- array(
- 'color: url( "http://example.com/invalid.gif" );',
- '',
- ),
- // Mismatched quotes.
- array(
- 'background-image: url( "http://example.com/valid.gif\' );',
- '',
- ),
- // Bad protocol, double quotes.
- array(
- 'background-image: url( "bad://example.com/invalid.gif" );',
- '',
- ),
- // Bad protocol, single quotes.
- array(
- "background-image: url( 'bad://example.com/invalid.gif' );",
- '',
- ),
- // Bad protocol, single quotes.
- array(
- "background-image: url( 'bad://example.com/invalid.gif' );",
- '',
- ),
- // Bad protocol, single quotes, strange spacing.
- array(
- "background-image: url( ' \tbad://example.com/invalid.gif ' );",
- '',
- ),
- // Bad protocol, no quotes.
- array(
- 'background-image: url( bad://example.com/invalid.gif );',
- '',
- ),
- // No URL inside url().
- array(
- 'background-image: url();',
- '',
- ),
- // Malformed, no closing `)`.
- array(
- 'background-image: url( "http://example.com" ;',
- '',
- ),
- // Malformed, no closing `"`.
- array(
- 'background-image: url( "http://example.com );',
- '',
- ),
- );
- }
- /**
- * Testing the safecss_filter_attr() function with the safecss_filter_attr_allow_css filter.
- *
- * @ticket 37134
- *
- * @dataProvider data_test_safecss_filter_attr_filtered
- *
- * @param string $css A string of CSS rules.
- * @param string $expected Expected string of CSS rules.
- */
- public function test_safecss_filter_attr_filtered( $css, $expected ) {
- add_filter( 'safecss_filter_attr_allow_css', '__return_true' );
- $this->assertSame( $expected, safecss_filter_attr( $css ) );
- remove_filter( 'safecss_filter_attr_allow_css', '__return_true' );
- }
- /**
- * Data Provider for test_safecss_filter_attr_filtered().
- *
- * @return array {
- * @type array {
- * @string string $css A string of CSS rules.
- * @string string $expected Expected string of CSS rules.
- * }
- * }
- */
- public function data_test_safecss_filter_attr_filtered() {
- return array(
- // A single attribute name, with a single value.
- array(
- 'css' => 'margin-top: 2px',
- 'expected' => 'margin-top: 2px',
- ),
- // Backslash \ can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'margin-top: \2px',
- 'expected' => 'margin-top: \2px',
- ),
- // Curly bracket } can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'margin-bottom: 2px}',
- 'expected' => 'margin-bottom: 2px}',
- ),
- // Parenthesis ) can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'margin-bottom: 2px)',
- 'expected' => 'margin-bottom: 2px)',
- ),
- // Ampersand & can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'margin-bottom: 2px&',
- 'expected' => 'margin-bottom: 2px&',
- ),
- // Expressions can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'height: expression( body.scrollTop + 50 + "px" )',
- 'expected' => 'height: expression( body.scrollTop + 50 + "px" )',
- ),
- // RGB color values can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'color: rgb( 100, 100, 100 )',
- 'expected' => 'color: rgb( 100, 100, 100 )',
- ),
- // RGBA color values can be allowed with the 'safecss_filter_attr_allow_css' filter.
- array(
- 'css' => 'color: rgb( 100, 100, 100, .4 )',
- 'expected' => 'color: rgb( 100, 100, 100, .4 )',
- ),
- );
- }
- /**
- * Test filtering a standard img tag.
- *
- * @ticket 50731
- */
- function test_wp_kses_img_tag_standard_attributes() {
- $html = array(
- '<img',
- 'loading="lazy"',
- 'src="https://example.com/img.jpg"',
- 'width="1000"',
- 'height="1000"',
- 'alt=""',
- 'class="wp-image-1000"',
- '/>',
- );
- $html = implode( ' ', $html );
- $this->assertSame( $html, wp_kses_post( $html ) );
- }
- }
|