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 039a8f275b..8c41e73215 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 @@ -2142,6 +2142,8 @@ class WP_HTML_Tag_Processor { * to the end of the updated document and return. */ if ( $requires_no_updating && $this->bytes_already_copied > 0 ) { + $this->html = $this->output_buffer . substr( $this->html, $this->bytes_already_copied ); + $this->bytes_already_copied = strlen( $this->output_buffer ); return $this->output_buffer . substr( $this->html, $this->bytes_already_copied ); } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php index 86d6153957..15123748ae 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php @@ -456,6 +456,26 @@ class Tests_HtmlApi_wpHtmlTagProcessor extends WP_UnitTestCase { ); } + /** + * Ensures that when seeking to an earlier spot in the document that + * all previously-enqueued updates are applied as they ought to be. + * + * @ticket 58160 + */ + public function test_get_updated_html_applies_updates_to_content_after_seeking_to_before_parsed_bytes() { + $p = new WP_HTML_Tag_Processor( '
' ); + + $p->next_tag(); + $p->set_attribute( 'wonky', true ); + $p->next_tag(); + $p->set_bookmark( 'here' ); + + $p->next_tag( array( 'tag_closers' => 'visit' ) ); + $p->seek( 'here' ); + + $this->assertSame( '
', $p->get_updated_html() ); + } + /** * @ticket 56299 *