diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 660e43ba659b4..336c83949c0dc 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -297,6 +297,15 @@ public static function create_fragment( $html, $context = '', $encoding = return null; } + if ( ! is_string( $html ) ) { + _doing_it_wrong( + __METHOD__, + __( 'The HTML parameter must be a string.' ), + '6.9.0' + ); + return null; + } + $context_processor = static::create_full_parser( "{$context}", $encoding ); if ( null === $context_processor ) { return null; @@ -339,6 +348,14 @@ public static function create_full_parser( $html, $known_definite_encoding = 'UT if ( 'UTF-8' !== $known_definite_encoding ) { return null; } + if ( ! is_string( $html ) ) { + _doing_it_wrong( + __METHOD__, + __( 'The HTML parameter must be a string.' ), + '6.9.0' + ); + return null; + } $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); $processor->state->encoding = $known_definite_encoding; diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 4f0f10a1a04f3..3d66f7e57d01b 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -834,6 +834,14 @@ class WP_HTML_Tag_Processor { * @param string $html HTML to process. */ public function __construct( $html ) { + if ( ! is_string( $html ) ) { + _doing_it_wrong( + __METHOD__, + __( 'The HTML parameter must be a string.' ), + '6.9.0' + ); + $html = ''; + } $this->html = $html; } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index 1ca60e691f03e..13e0728ca912a 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -36,6 +36,28 @@ public function test_warns_that_the_static_creator_methods_should_be_called_inst new WP_HTML_Processor( '

Light roast.

' ); } + /** + * @ticket 63854 + * + * @covers ::create_fragment + * @expectedIncorrectUsage WP_HTML_Processor::create_fragment + */ + public function test_create_fragment_validates_html_parameter() { + $processor = WP_HTML_Processor::create_fragment( null ); + $this->assertNull( $processor ); + } + + /** + * @ticket 63854 + * + * @covers ::create_full_parser + * @expectedIncorrectUsage WP_HTML_Processor::create_full_parser + */ + public function test_create_full_parser_validates_html_parameter() { + $processor = WP_HTML_Processor::create_full_parser( null ); + $this->assertNull( $processor ); + } + /** * Once stepping to the end of the document, WP_HTML_Processor::get_tag * should no longer report a tag. It should report `null` because there diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php index 6a06109eafe13..53bba243a99a0 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php @@ -72,6 +72,23 @@ public function test_has_self_closing_flag_matches_input_html( $html, $flag_is_s } } + /** + * @ticket 63854 + * + * @covers WP_HTML_Tag_Processor::__construct + * @expectedIncorrectUsage WP_HTML_Tag_Processor::__construct + */ + public function test_constructor_validates_html_parameter() { + // Test that passing null triggers _doing_it_wrong and sets HTML to empty string. + $processor = new WP_HTML_Tag_Processor( null ); + + // Verify that the HTML was set to an empty string. + $this->assertSame( '', $processor->get_updated_html(), 'HTML should be set to empty string when null is passed' ); + + // Verify that next_token() works without errors (indicating the processor is in a valid state). + $this->assertFalse( $processor->next_token(), 'next_token() should work without errors when HTML is empty string' ); + } + /** * Data provider. HTML tags which might have a self-closing flag, and an indicator if they do. *