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..8988de987548b --- /dev/null +++ b/tests/phpunit/tests/functions/getTagRegex.php @@ -0,0 +1,95 @@ +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 void element (an iframe cannot self-close), matched + // both with and without the space before the slash (comment:16). + 'a self-closing tag with a space' => array( + 'input', + '', + array( '' ), + ), + + 'a self-closing tag without a space' => array( + 'input', + '', + array( '' ), + ), + + 'a tag with a multiline body' => array( + 'video', + "", + array( "" ), + ), + + 'no match when the tag is absent' => array( + 'iframe', + '

No embeds here.

', + array(), + ), + ); + } + + /** + * @ticket 26674 + */ + public function test_get_tag_regex_returns_empty_string_for_empty_tag() { + $this->assertSame( '', get_tag_regex( '' ) ); + } + + /** + * The tag name is passed through tag_escape(), so casing and invalid + * characters do not change the generated pattern. + * + * @ticket 26674 + */ + public function test_get_tag_regex_escapes_the_tag_name() { + $this->assertSame( get_tag_regex( 'iframe' ), get_tag_regex( 'IFRAME' ) ); + } +}