From 711eee76c99dd2880d23674bc98cc66cfa342327 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 8 Aug 2024 17:20:31 +0200 Subject: [PATCH 1/3] Add test covering self-closing script tags in svg --- tests/phpunit/tests/html-api/wpHtmlProcessor.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index 68c60a1ff85cc..a62db2d0155d2 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -503,4 +503,12 @@ public function __construct( $html ) { $subclass_processor = call_user_func( array( get_class( $subclass_instance ), 'create_fragment' ), '' ); $this->assertInstanceOf( get_class( $subclass_instance ), $subclass_processor, '::create_fragment did not return subclass instance.' ); } + + /** + * @ticket 61576 + */ + public function test_foreign_content_script_self_closing() { + $processor = WP_HTML_Processor::create_fragment( '' ); + $this->assertTrue( $processor->next_tag( 'script' ) ); + } } From 28e1e778aea245dffc6583635436e8c563f786c7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 8 Aug 2024 17:21:22 +0200 Subject: [PATCH 2/3] Fix self-closing svg:script tag behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The spec seems to have been misinterpreted, although the result was ultimately the same. > If the token has its self-closing flag set, then run the appropriate steps from the following list: > > If the token's tag name is "script", and the new current node is in the SVG namespace > Acknowledge the token's self-closing flag, and then act as described in the steps for a "script" end tag below. > … > An end tag whose tag name is "script", if the current node is an SVG script element --- src/wp-includes/html-api/class-wp-html-processor.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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 3820fe027723d..e43cf611a458e 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -4243,12 +4243,8 @@ private function step_in_foreign_content(): bool { /* * > Acknowledge the token's self-closing flag, and then act as * > described in the steps for a "script" end tag below. - * - * @todo Verify that this shouldn't be handled by the rule for - * "An end tag whose name is 'script', if the current node - * is an SVG script element." */ - goto in_foreign_content_any_other_end_tag; + goto in_foreign_content_svg_script_close_tag; } else { $this->state->stack_of_open_elements->pop(); } @@ -4260,14 +4256,15 @@ private function step_in_foreign_content(): bool { * > An end tag whose name is "script", if the current node is an SVG script element. */ if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) { + in_foreign_content_svg_script_close_tag: $this->state->stack_of_open_elements->pop(); + return true; } /* * > Any other end tag */ if ( $this->is_tag_closer() ) { - in_foreign_content_any_other_end_tag: $node = $this->state->stack_of_open_elements->current_node(); if ( $tag_name !== $node->node_name ) { // @todo Indicate a parse error once it's possible. From e29b20701eec9d216987ae4452fbd27e27de0005 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Thu, 8 Aug 2024 09:37:42 -0700 Subject: [PATCH 3/3] Avoid separating the self-closing rules, remove the goto. --- .../html-api/class-wp-html-processor.php | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) 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 9d15539d29937..2bb6302c99781 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -4239,17 +4239,22 @@ private function step_in_foreign_content(): bool { /* * > If the token has its self-closing flag set, then run * > the appropriate steps from the following list: + * > + * > ↪ the token's tag name is "script", and the new current node is in the SVG namespace + * > Acknowledge the token's self-closing flag, and then act as + * > described in the steps for a "script" end tag below. + * > + * > ↪ Otherwise + * > Pop the current node off the stack of open elements and + * > acknowledge the token's self-closing flag. + * + * Since the rules for SCRIPT below indicate to pop the element off of the stack of + * open elements, which is the same for the Otherwise condition, there's no need to + * separate these checks. The difference comes when a parser operates with the scripting + * flag enabled, and executes the script, which this parser does not support. */ if ( $this->state->current_token->has_self_closing_flag ) { - if ( 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) { - /* - * > Acknowledge the token's self-closing flag, and then act as - * > described in the steps for a "script" end tag below. - */ - goto in_foreign_content_svg_script_close_tag; - } else { - $this->state->stack_of_open_elements->pop(); - } + $this->state->stack_of_open_elements->pop(); } return true; } @@ -4258,7 +4263,6 @@ private function step_in_foreign_content(): bool { * > An end tag whose name is "script", if the current node is an SVG script element. */ if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) { - in_foreign_content_svg_script_close_tag: $this->state->stack_of_open_elements->pop(); return true; }