From 4026237dadd2f4c1f11ba4a89605e8f394c11f38 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Thu, 8 Aug 2024 04:24:03 +0000 Subject: [PATCH] HTML API: Ensure that `get_modifiable_text()` reads enqueued updates. When `set_modifiable_text()` was added to the Tag Processor, it was considered that the same information could be queried after setting its value and before proceeding to the next token, but unfortunately overlooked that if the starting modifiable text length was zero, then the read in `get_modifiable_text()` would ignore enqueued updates. In this patch, `get_modifiable_text()` will read any enqueued values before reading from the input HTML document to ensure consistency. Follow-up to [58829]. Props dmsnell, jonsurrell, ramonopoly. Fixes #61617. git-svn-id: https://develop.svn.wordpress.org/trunk@58866 602fd350-edb4-49c9-b593-d223f7449a82 --- .../html-api/class-wp-html-tag-processor.php | 8 +- .../wpHtmlTagProcessorModifiableText.php | 77 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) 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 fcf418e856d5e..0ff2cdc4dd10d 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 @@ -614,7 +614,7 @@ class WP_HTML_Tag_Processor { * * @since 6.5.0 * - * @var string + * @var int */ private $text_length; @@ -2894,11 +2894,13 @@ public function get_comment_type(): ?string { * @return string */ public function get_modifiable_text(): string { - if ( null === $this->text_starts_at || 0 === $this->text_length ) { + $has_enqueued_update = isset( $this->lexical_updates['modifiable text'] ); + + if ( ! $has_enqueued_update && ( null === $this->text_starts_at || 0 === $this->text_length ) ) { return ''; } - $text = isset( $this->lexical_updates['modifiable text'] ) + $text = $has_enqueued_update ? $this->lexical_updates['modifiable text']->text : substr( $this->html, $this->text_starts_at, $this->text_length ); diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessorModifiableText.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessorModifiableText.php index 717d061016a2d..03c65321e34bd 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessorModifiableText.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessorModifiableText.php @@ -39,6 +39,83 @@ public function test_get_modifiable_text_is_idempotent() { } } + /** + * Ensures that `get_modifiable_text()` reads enqueued updates when read + * from after writing; guarantees consistency through writes. + * + * @ticket 61617 + */ + public function test_get_modifiable_text_is_consistent_after_writes() { + $before = 'just some text'; + $after = 'different text'; + $processor = new WP_HTML_Tag_Processor( $before ); + $processor->next_token(); + + $this->assertSame( + '#text', + $processor->get_token_name(), + "Should have found text node but found '{$processor->get_token_name()}' instead: check test setup." + ); + + $this->assertSame( + $before, + $processor->get_modifiable_text(), + 'Should have found initial test text: check test setup.' + ); + + $processor->set_modifiable_text( $after ); + $this->assertSame( + $after, + $processor->get_modifiable_text(), + 'Should have found enqueued updated text.' + ); + + $processor->get_updated_html(); + $this->assertSame( + $after, + $processor->get_modifiable_text(), + 'Should have found updated text.' + ); + } + + /** + * Ensures that `get_modifiable_text()` reads enqueued updates when read from after + * writing when starting from an empty text; guarantees consistency through writes. + * + * @ticket 61617 + */ + public function test_get_modifiable_text_is_consistent_after_writes_to_empty_text() { + $after = 'different text'; + $processor = new WP_HTML_Tag_Processor( '' ); + $processor->next_token(); + + $this->assertSame( + 'SCRIPT', + $processor->get_token_name(), + "Should have found text node but found '{$processor->get_token_name()}' instead: check test setup." + ); + + $this->assertSame( + '', + $processor->get_modifiable_text(), + 'Should have found initial test text: check test setup.' + ); + + $processor->set_modifiable_text( $after ); + $this->assertSame( + $after, + $processor->get_modifiable_text(), + 'Should have found enqueued updated text.' + ); + + $processor->get_updated_html(); + $this->assertSame( + $after, + $processor->get_modifiable_text(), + 'Should have found updated text.' + ); + } + /** * Ensures that updates to modifiable text that are shorter than the * original text do not cause the parser to lose its orientation.