From 786c763e5cc8409a75fa2250ac096dbcec0797a6 Mon Sep 17 00:00:00 2001 From: Prakritee Sharma Date: Fri, 18 Sep 2026 11:18:12 +0545 Subject: [PATCH] Emoji: Don't staticize emoji in ignored tags that have attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Emoji inside ignored tags (code, pre, style, script, textarea) should not be staticized, but wp_staticize_emoji() only recognised such a tag when it closed immediately after the tag name. Tags with attributes — e.g. the block editor's Code/Preformatted block, which adds class="wp-block-code" to
 — were not
detected, so emoji inside them were converted to  in feeds and email.

This applies the same [^>]* tolerance already used by convert_smilies(), whose
identical bug was fixed in [45569] / #47489. Adds unit tests covering all five
ignored tags, with and without attributes.
---
 src/wp-includes/formatting.php           |  2 +-
 tests/phpunit/tests/formatting/emoji.php | 42 ++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php
index 5bf001c430a49..a928c82ed367d 100644
--- a/src/wp-includes/formatting.php
+++ b/src/wp-includes/formatting.php
@@ -6187,7 +6187,7 @@ function wp_staticize_emoji( $text ) {
 		$content = $textarr[ $i ];
 
 		// If we're in an ignore block, wait until we find its closing tag.
-		if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
+		if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')[^>]*>/', $content, $matches ) ) {
 			$ignore_block_element = $matches[1];
 		}
 
diff --git a/tests/phpunit/tests/formatting/emoji.php b/tests/phpunit/tests/formatting/emoji.php
index d885c49fd7289..3bcddf9897c5c 100644
--- a/tests/phpunit/tests/formatting/emoji.php
+++ b/tests/phpunit/tests/formatting/emoji.php
@@ -376,4 +376,46 @@ public function data_wp_staticize_emoji() {
 	public function test_wp_staticize_emoji( $emoji, $expected ) {
 		$this->assertSame( $expected, wp_staticize_emoji( $emoji ) );
 	}
+
+	/**
+	 * Emoji inside ignored tags (code, pre, style, script, textarea) should not be
+	 * staticized, even when the tag has attributes.
+	 *
+	 * This mirrors the fix made to convert_smilies() in #47489, which was never
+	 * applied to the parallel logic in wp_staticize_emoji().
+	 *
+	 * @ticket 66134
+	 * @dataProvider data_wp_staticize_emoji_ignored_tags
+	 *
+	 * @covers ::wp_staticize_emoji
+	 *
+	 * @param string $element The ignored element name.
+	 */
+	public function test_wp_staticize_emoji_ignores_tags_with_attributes( $element ) {
+		// Emoji U+1F642 as the HTML entity produced by _wp_emoji_list( 'entities' ).
+		$emoji = '🙂';
+
+		// Without attributes (already worked before the fix).
+		$no_attr = "<$element>$emoji";
+		$this->assertSame( $no_attr, wp_staticize_emoji( $no_attr ), "Emoji inside <$element> should not be staticized." );
+
+		// With attributes (regressed: the Preformatted/Code block adds a class).
+		$with_attr = "<$element class=\"wp-block-code\">$emoji";
+		$this->assertSame( $with_attr, wp_staticize_emoji( $with_attr ), "Emoji inside <$element class=\"...\"> should not be staticized." );
+	}
+
+	/**
+	 * Data provider for test_wp_staticize_emoji_ignores_tags_with_attributes().
+	 *
+	 * @return array[]
+	 */
+	public function data_wp_staticize_emoji_ignored_tags() {
+		return array(
+			'code'     => array( 'code' ),
+			'pre'      => array( 'pre' ),
+			'style'    => array( 'style' ),
+			'script'   => array( 'script' ),
+			'textarea' => array( 'textarea' ),
+		);
+	}
 }