From c3df3ef9cf2405d918542dded23f31405c3e28ed Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 15 May 2024 17:42:10 +0000 Subject: [PATCH] Improve legibility of JSON-encoded Interactivity API store data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Interactivity API has been rendering client data in a SCRIPT element with the type `application/json` so that it's not executed as a script, but is available to one. The data runs through `wp_json_encode()` and is encoded with some flags to ensure that potentially-dangerous characters are escaped. However, this can lead to some challenges. Eagerly escaping when not necessary can make the data difficult to comprehend when reading the output HTML. For example, all non-ASCII Unicode characters are escaped with their code point equivalent. This results in `\ud83c\udd70` instead of `🅰`. In this patch, the flags for JSON encoding are refined to ensure what's necessary while relaxing other rules (leaving in those Unicode characters if the blog charset is UTF-8). This makes for Interactivity API data that's quicker as a human reader to decipher and diagnose. In summary: - This data is JSON encoded and printed in a ` + * + * A script tag must be closed by a sequence beginning with `` will be printed as `\u003C/script\u00E3`. + * + * - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E. + * - JSON_UNESCAPED_SLASHES: Don't escape /. + * + * If the page will use UTF-8 encoding, it's safe to print unescaped unicode: + * + * - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally (instead of as `\uXXXX`). + * - JSON_UNESCAPED_LINE_TERMINATORS: The line terminators are kept unescaped when + * JSON_UNESCAPED_UNICODE is supplied. It uses the same behaviour as it was + * before PHP 7.1 without this constant. Available as of PHP 7.1.0. + * + * The JSON specification requires encoding in UTF-8, so if the generated HTML page + * is not encoded in UTF-8 then it's not safe to include those literals. They must + * be escaped to avoid encoding issues. + * + * @see https://www.rfc-editor.org/rfc/rfc8259.html for details on encoding requirements. + * @see https://www.php.net/manual/en/json.constants.php for details on these constants. + * @see https://html.spec.whatwg.org/#script-data-state for details on script tag parsing. + */ + $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS; + if ( ! is_utf8_charset() ) { + $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; + } + wp_print_inline_script_tag( wp_json_encode( $interactivity_data, - JSON_HEX_TAG | JSON_HEX_AMP + $json_encode_flags ), array( 'type' => 'application/json', diff --git a/wp-includes/version.php b/wp-includes/version.php index 4b0e3fa702..39b1078559 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.6-alpha-58157'; +$wp_version = '6.6-alpha-58159'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.