diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 35d91fad3129c..b05da8a80e99d 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1498,6 +1498,7 @@ public function serialize_token(): string { case 'SCRIPT': case 'STYLE': + case 'XMP': break; default: diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-serialize.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-serialize.php index e516addb6c314..6af164beea7c8 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-serialize.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-serialize.php @@ -134,6 +134,19 @@ public function test_style_contents_are_not_escaped() { ); } + /** + * Ensures that XMP contents are not escaped, as they are not parsed like text nodes are. + * + * @ticket 62036 + */ + public function test_xmp_contents_are_not_escaped() { + $this->assertSame( + WP_HTML_Processor::normalize( "apples > or\x00anges & pears < plums" ), + "apples > or\u{FFFD}anges & pears < plums", + 'Should have preserved text inside an XMP element, except for replacing NULL bytes.' + ); + } + public function test_unexpected_closing_tags_are_removed() { $this->assertSame( WP_HTML_Processor::normalize( 'onetwothree' ), @@ -493,6 +506,7 @@ public static function data_provider_normalized_fuzzer_cases_that_should_be_idem 'FORM with SVG TITLE text edge' => array( "
" ), 'FORM with TABLE and SCRIPT' => array( '
' ), 'FORM with TABLE CAPTION' => array( '
' ), + 'XMP rawtext with entity-looking text' => array( 'apples > oranges &amp; <' ), 'Short malformed G attribute C' => array( '' ), 'Short malformed G attribute S' => array( '' ), 'Duplicate SRC boundary' => array( '' ),