From 72bc81c048d48cc9464b2d43657dde9c4d4de79a Mon Sep 17 00:00:00 2001 From: dmsnell Date: Wed, 4 Sep 2024 19:25:14 +0000 Subject: [PATCH] HTML API: Only examine HTML nodes in `pop_until()` instack of open elements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `pop_until( $tag_name )` method in the stack of open elements should only be examining HTML elements, but it has only been checking the tag name. This has led to closing the wrong tags when run from inside foreign content. A very specific situation where this may arise is when a `TEMPLATE` closer is found inside foreign content, inside another template. {{{ HTML:template SVG:template HTML:/template
╰──< this outer TEMPLATE is closed by this one >───╯ }}} This patch constains the method to checking for elements matching the tag name which are in the HTML namespace so that the proper detection occurs. Developed in https://github.com/WordPress/wordpress-develop/pull/7286 Discussed in https://core.trac.wordpress.org/ticket/61576 Follow-up to [58867]. Props dmsnell, jonsurrell. See #61576. Built from https://develop.svn.wordpress.org/trunk@58992 git-svn-id: http://core.svn.wordpress.org/trunk@58388 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- .../html-api/class-wp-html-open-elements.php | 18 +++++++++--------- .../html-api/class-wp-html-processor.php | 9 +++++++++ wp-includes/version.php | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/wp-includes/html-api/class-wp-html-open-elements.php b/wp-includes/html-api/class-wp-html-open-elements.php index 5ce1f8feb5..cb913853f0 100644 --- a/wp-includes/html-api/class-wp-html-open-elements.php +++ b/wp-includes/html-api/class-wp-html-open-elements.php @@ -530,31 +530,31 @@ class WP_HTML_Open_Elements { } /** - * Pops nodes off of the stack of open elements until one with the given tag name has been popped. + * Pops nodes off of the stack of open elements until an HTML tag with the given name has been popped. * * @since 6.4.0 * * @see WP_HTML_Open_Elements::pop * - * @param string $tag_name Name of tag that needs to be popped off of the stack of open elements. + * @param string $html_tag_name Name of tag that needs to be popped off of the stack of open elements. * @return bool Whether a tag of the given name was found and popped off of the stack of open elements. */ - public function pop_until( string $tag_name ): bool { + public function pop_until( string $html_tag_name ): bool { foreach ( $this->walk_up() as $item ) { - if ( 'context-node' === $item->bookmark_name ) { - return true; - } - $this->pop(); + if ( 'html' !== $item->namespace ) { + continue; + } + if ( - '(internal: H1 through H6 - do not use)' === $tag_name && + '(internal: H1 through H6 - do not use)' === $html_tag_name && in_array( $item->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { return true; } - if ( $tag_name === $item->node_name ) { + if ( $html_tag_name === $item->node_name ) { return true; } } diff --git a/wp-includes/html-api/class-wp-html-processor.php b/wp-includes/html-api/class-wp-html-processor.php index 55b9061368..cb581fac39 100644 --- a/wp-includes/html-api/class-wp-html-processor.php +++ b/wp-includes/html-api/class-wp-html-processor.php @@ -5428,6 +5428,11 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { } } + // All of the following rules are for matching HTML elements. + if ( 'html' !== $node->namespace ) { + continue; + } + switch ( $node->node_name ) { /* * > 4. If node is a `select` element, run these substeps: @@ -5443,6 +5448,10 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { case 'SELECT': if ( ! $last ) { foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $ancestor ) { + if ( 'html' !== $ancestor->namespace ) { + continue; + } + switch ( $ancestor->node_name ) { /* * > 5. If _ancestor_ is a `template` node, jump to the step below diff --git a/wp-includes/version.php b/wp-includes/version.php index 5e202be177..fc15073f1d 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.7-alpha-58988'; +$wp_version = '6.7-alpha-58992'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.