From a67542b691044470a8b6d2295efd19dec169b2b5 Mon Sep 17 00:00:00 2001 From: gunjanjaswal Date: Thu, 13 Aug 2026 19:03:28 +0530 Subject: [PATCH 1/3] Formatting: make get_tag_regex() match tags non-greedily. get_tag_regex() built a pattern with a greedy body match, so content with more than one tag of the same type matched from the first opening tag through the last closing tag, merging every tag in between (and the text between them) into a single match. Make the attribute and body matches lazy, aligning get_tag_regex() with the pattern get_media_embedded_in_content() already uses. Adds unit tests for get_tag_regex(), which previously had none, and refreshes the stale patch. Props kopepasah, afercia. Fixes #26674. --- src/wp-includes/functions.php | 2 +- tests/phpunit/tests/functions/getTagRegex.php | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/tests/functions/getTagRegex.php diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index f5002a45de1e8..80880c3121a0b 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -7679,7 +7679,7 @@ function get_tag_regex( $tag ) { if ( empty( $tag ) ) { return ''; } - return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) ); + return sprintf( '<%1$s[^<]*?(?:>[\s\S]*?<\/%1$s>|\s*\/>)', tag_escape( $tag ) ); } /** diff --git a/tests/phpunit/tests/functions/getTagRegex.php b/tests/phpunit/tests/functions/getTagRegex.php new file mode 100644 index 0000000000000..45c3c883dd3ae --- /dev/null +++ b/tests/phpunit/tests/functions/getTagRegex.php @@ -0,0 +1,87 @@ +assertSame( $expected, $matches[0] ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_get_tag_regex_matches() { + return array( + 'a single tag with a body' => array( + 'iframe', + '', + array( '' ), + ), + + // The regression: a greedy match ran from the first opening tag to + // the last closing tag, merging both embeds and the text between + // them into a single match. See #26674. + 'two adjacent tags are matched separately' => array( + 'iframe', + ' text ', + array( + '', + '', + ), + ), + + 'a self-closing tag' => array( + 'iframe', + '', array( '' ), @@ -39,7 +39,7 @@ public function data_get_tag_regex_matches() { // The regression: a greedy match ran from the first opening tag to // the last closing tag, merging both embeds and the text between // them into a single match. See #26674. - 'two adjacent tags are matched separately' => array( + 'two adjacent tags are matched separately' => array( 'iframe', ' text ', array( @@ -48,19 +48,19 @@ public function data_get_tag_regex_matches() { ), ), - 'a self-closing tag' => array( + 'a self-closing tag' => array( 'iframe', '