From c265e9022ddac98cf73a91b49004125166dc46ba Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Tue, 22 Aug 2023 12:09:05 -0500 Subject: [PATCH 1/2] HTML API: Stop proceeding HTML when encountering unsupported markup. It was a design goal of the HTML Processor to abort processing its input document when encountering unsupported markup. Unfortunately there was no test for this and so-far, the HTML Processor has paused, but continued processing in these situations. In this patch a new test ensures that the HTML Processor stops and refuses to move forward after encountering any unsupported markup. It also ensures that it doesn't report any current tag names since unsupported markup could imply that the read tag name is different than the parsed tag name. --- .../html-api/class-wp-html-processor.php | 9 +++++ .../tests/html-api/wpHtmlProcessor.php | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+) 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 6e1723494c2e9..b5a20dbd82cdc 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -432,6 +432,11 @@ public function next_tag( $query = null ) { * @return bool Whether a tag was matched. */ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { + // Refuse to proceed if there was a previous error. + if ( null !== $this->last_error ) { + return false; + } + if ( self::PROCESS_NEXT_NODE === $node_to_process ) { $top_node = $this->state->stack_of_open_elements->current_node(); if ( $top_node && self::is_void( $top_node->node_name ) ) { @@ -744,6 +749,10 @@ private function bookmark_tag() { * @return string|null Name of currently matched tag in input HTML, or `null` if none found. */ public function get_tag() { + if ( null !== $this->last_error ) { + return null; + } + $tag_name = parent::get_tag(); switch ( $tag_name ) { diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index 6a666c19cf27c..a05401d8a7c01 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -42,6 +42,40 @@ public function test_warns_that_the_static_creator_methods_should_be_called_inst ); } + /** + * 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 + * is no tag matched or open. + * + * @ticket {TICKET_NUMBER} + * + * @covers WP_HTML_Processor::get_tag + */ + public function test_get_tag_is_null_once_document_is_finished() { + $p = WP_HTML_Processor::createFragment( '
Test
' ); + $p->next_tag(); + $this->assertSame( 'DIV', $p->get_tag() ); + + $this->assertFalse( $p->next_tag() ); + $this->assertNull( $p->get_tag() ); + } + + /** + * Ensures that if the HTML Processor encounters inputs that it can't properly handle, + * that it stops processing the rest of the document. This prevents data corruption. + * + * @ticket {TICKET_NUMBER} + * + * @covers WP_HTML_Processor::next_tag + */ + public function test_stops_processing_after_unsupported_elements() { + $p = WP_HTML_Processor::createFragment( '

' ); + $p->next_tag( 'P' ); + $this->assertFalse( $p->next_tag(), 'Stepped into a tag after encountering X-NOT-SUPPORTED element when it should have aborted.' ); + $this->assertNull( $p->get_tag(), "Should have aborted processing, but still reported tag {$p->get_tag()} after properly failing to step into tag." ); + $this->assertFalse( $p->next_tag( 'P' ), 'Stepped into normal P element after X-NOT-SUPPORTED element when it should have aborted.' ); + } + /** * Ensures that the HTML Processor maintains its internal state through seek calls. * From 9cc1258251930cab8ada3abd28b6a1def477fca9 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Tue, 22 Aug 2023 11:20:13 -0600 Subject: [PATCH 2/2] Add Trac ticket reference --- tests/phpunit/tests/html-api/wpHtmlProcessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index a05401d8a7c01..d6b818dd44c34 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -47,7 +47,7 @@ public function test_warns_that_the_static_creator_methods_should_be_called_inst * should no longer report a tag. It should report `null` because there * is no tag matched or open. * - * @ticket {TICKET_NUMBER} + * @ticket 59167 * * @covers WP_HTML_Processor::get_tag */ @@ -64,7 +64,7 @@ public function test_get_tag_is_null_once_document_is_finished() { * Ensures that if the HTML Processor encounters inputs that it can't properly handle, * that it stops processing the rest of the document. This prevents data corruption. * - * @ticket {TICKET_NUMBER} + * @ticket 59167 * * @covers WP_HTML_Processor::next_tag */