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 95216b08a1988..11a0daa4b26f4 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 @@ -4009,7 +4009,13 @@ private function matches(): bool { } // Does the tag name match the requested tag name in a case-insensitive manner? - if ( isset( $this->sought_tag_name ) && 0 !== substr_compare( $this->html, $this->sought_tag_name, $this->tag_name_starts_at, $this->tag_name_length, true ) ) { + if ( + isset( $this->sought_tag_name ) && + ( + strlen( $this->sought_tag_name ) !== $this->tag_name_length || + 0 !== substr_compare( $this->html, $this->sought_tag_name, $this->tag_name_starts_at, $this->tag_name_length, true ) + ) + ) { return false; } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php index b9c6817988032..908e286a8fb21 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php @@ -601,6 +601,31 @@ public function test_next_tag_should_return_false_for_a_non_existing_tag() { $this->assertFalse( $processor->next_tag( 'p' ), 'Querying a non-existing tag did not return false' ); } + /** + * @ticket 61545 + */ + public function test_next_tag_should_not_match_on_substrings_of_a_requested_tag() { + $processor = new WP_HTML_Tag_Processor( '

' ); + + $this->assertTrue( + $processor->next_tag( 'PICTURE' ), + 'Failed to find a tag when requested: check test setup.' + ); + + $this->assertSame( + 'PICTURE', + $processor->get_tag(), + 'Should have skipped past substring tag matches, directly finding the PICTURE element.' + ); + + $processor = new WP_HTML_Tag_Processor( '

' ); + + $this->assertFalse( + $processor->next_tag( 'PICTURE' ), + "Should not have found any PICTURE element, but found '{$processor->get_token_name()}' instead." + ); + } + /** * @ticket 59209 *