Skip to content

Commit 055010b

Browse files
committed
HTML API: Ensure non-string HTML input is safely handled.
Prevents an issue where passing `null` to HTML API constructors could result in runtime errors. Developed in #9545. Props kraftbj, jonsurrell, westonruter. Fixes #63854. git-svn-id: https://develop.svn.wordpress.org/trunk@60887 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 2fe26ce commit 055010b

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

src/wp-includes/html-api/class-wp-html-processor.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,15 @@ public static function create_fragment( $html, $context = '<body>', $encoding =
297297
return null;
298298
}
299299

300+
if ( ! is_string( $html ) ) {
301+
_doing_it_wrong(
302+
__METHOD__,
303+
__( 'The HTML parameter must be a string.' ),
304+
'6.9.0'
305+
);
306+
return null;
307+
}
308+
300309
$context_processor = static::create_full_parser( "<!DOCTYPE html>{$context}", $encoding );
301310
if ( null === $context_processor ) {
302311
return null;
@@ -339,6 +348,14 @@ public static function create_full_parser( $html, $known_definite_encoding = 'UT
339348
if ( 'UTF-8' !== $known_definite_encoding ) {
340349
return null;
341350
}
351+
if ( ! is_string( $html ) ) {
352+
_doing_it_wrong(
353+
__METHOD__,
354+
__( 'The HTML parameter must be a string.' ),
355+
'6.9.0'
356+
);
357+
return null;
358+
}
342359

343360
$processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE );
344361
$processor->state->encoding = $known_definite_encoding;

src/wp-includes/html-api/class-wp-html-tag-processor.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,14 @@ class WP_HTML_Tag_Processor {
834834
* @param string $html HTML to process.
835835
*/
836836
public function __construct( $html ) {
837+
if ( ! is_string( $html ) ) {
838+
_doing_it_wrong(
839+
__METHOD__,
840+
__( 'The HTML parameter must be a string.' ),
841+
'6.9.0'
842+
);
843+
$html = '';
844+
}
837845
$this->html = $html;
838846
}
839847

tests/phpunit/tests/html-api/wpHtmlProcessor.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,28 @@ public function test_warns_that_the_static_creator_methods_should_be_called_inst
3636
new WP_HTML_Processor( '<p>Light roast.</p>' );
3737
}
3838

39+
/**
40+
* @ticket 63854
41+
*
42+
* @covers ::create_fragment
43+
* @expectedIncorrectUsage WP_HTML_Processor::create_fragment
44+
*/
45+
public function test_create_fragment_validates_html_parameter() {
46+
$processor = WP_HTML_Processor::create_fragment( null );
47+
$this->assertNull( $processor );
48+
}
49+
50+
/**
51+
* @ticket 63854
52+
*
53+
* @covers ::create_full_parser
54+
* @expectedIncorrectUsage WP_HTML_Processor::create_full_parser
55+
*/
56+
public function test_create_full_parser_validates_html_parameter() {
57+
$processor = WP_HTML_Processor::create_full_parser( null );
58+
$this->assertNull( $processor );
59+
}
60+
3961
/**
4062
* Once stepping to the end of the document, WP_HTML_Processor::get_tag
4163
* should no longer report a tag. It should report `null` because there

tests/phpunit/tests/html-api/wpHtmlTagProcessor.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ public function test_has_self_closing_flag_matches_input_html( $html, $flag_is_s
7272
}
7373
}
7474

75+
/**
76+
* @ticket 63854
77+
*
78+
* @covers WP_HTML_Tag_Processor::__construct
79+
* @expectedIncorrectUsage WP_HTML_Tag_Processor::__construct
80+
*/
81+
public function test_constructor_validates_html_parameter() {
82+
// Test that passing null triggers _doing_it_wrong and sets HTML to empty string.
83+
$processor = new WP_HTML_Tag_Processor( null );
84+
85+
// Verify that the HTML was set to an empty string.
86+
$this->assertSame( '', $processor->get_updated_html(), 'HTML should be set to empty string when null is passed' );
87+
88+
// Verify that next_token() works without errors (indicating the processor is in a valid state).
89+
$this->assertFalse( $processor->next_token(), 'next_token() should work without errors when HTML is empty string' );
90+
}
91+
7592
/**
7693
* Data provider. HTML tags which might have a self-closing flag, and an indicator if they do.
7794
*

0 commit comments

Comments
 (0)