From 41532d5638063762e93e03f9bc5283dd6897e31a Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sat, 17 Feb 2024 15:28:04 +0000 Subject: [PATCH] Interactivity API: Skip instead of bail out if HTML contains `SVG` or `MATH`. Addresses an issue with server-side processing of directives when there is e.g. an SVG icon a navigation menu. Props cbravobernal, westonruter, dmsnell, swissspidy. Fixes #60517. Built from https://develop.svn.wordpress.org/trunk@57649 git-svn-id: http://core.svn.wordpress.org/trunk@57150 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- ...interactivity-api-directives-processor.php | 33 +++++++++++++++++++ .../class-wp-interactivity-api.php | 9 +++-- wp-includes/version.php | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php b/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php index 24201e82fd..3b2dcb1237 100644 --- a/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php +++ b/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php @@ -180,6 +180,39 @@ final class WP_Interactivity_API_Directives_Processor extends WP_HTML_Tag_Proces return array( $opener_tag, $closer_tag ); } + /** + * Skips processing the content between tags. + * + * It positions the cursor in the closer tag of the foreign element, if it + * exists. + * + * This function is intended to skip processing SVG and MathML inner content + * instead of bailing out the whole processing. + * + * @since 6.5.0 + * + * @access private + * + * @return bool Whether the foreign content was successfully skipped. + */ + public function skip_to_tag_closer(): bool { + $depth = 1; + $tag_name = $this->get_tag(); + while ( $depth > 0 && $this->next_tag( + array( + 'tag_name' => $tag_name, + 'tag_closers' => 'visit', + ) + ) ) { + if ( $this->has_self_closing_flag() ) { + continue; + } + $depth += $this->is_tag_closer() ? -1 : 1; + } + + return 0 === $depth; + } + /** * Finds the matching closing tag for an opening tag. * diff --git a/wp-includes/interactivity-api/class-wp-interactivity-api.php b/wp-includes/interactivity-api/class-wp-interactivity-api.php index 536b6623e2..9e5b1be1fa 100644 --- a/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -235,9 +235,14 @@ final class WP_Interactivity_API { while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { $tag_name = $p->get_tag(); + /* + * Directives inside SVG and MATH tags are not processed, + * as they are not compatible with the Tag Processor yet. + * We still process the rest of the HTML. + */ if ( 'SVG' === $tag_name || 'MATH' === $tag_name ) { - $unbalanced = true; - break; + $p->skip_to_tag_closer(); + continue; } if ( $p->is_tag_closer() ) { diff --git a/wp-includes/version.php b/wp-includes/version.php index ddcb7b75cd..6d9f86df82 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.5-beta1-57648'; +$wp_version = '6.5-beta1-57649'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.