Skip to content

Commit

Permalink
Better JSON encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
sirreal committed May 14, 2024
1 parent 60eb2f5 commit f9f1610
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions lib/experimental/script-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,53 @@ function gutenberg_print_script_module_data(): void {
}

foreach ( array_keys( $modules ) as $module_id ) {
$config = apply_filters( 'gb_scriptmoduledata_' . $module_id, array() );
if ( ! empty( $config ) ) {
$data = apply_filters( 'gb_scriptmoduledata_' . $module_id, array() );
if ( ! empty( $data ) ) {
/*
* This data will be printed as JSON inside a script tag like this:
* <script type="application/json"></script>
*
* A script tag must be closed by a sequence beginning with `</`. It's impossible to
* close a script tag without using `<`. We ensure that `<` is escaped and `/` can
* remain unescaped, so `</script>` will be printed as `\u003C/script\u00E3`.
*
* - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E.
* - JSON_UNESCAPED_SLASHES: Don't escape /.
*
* @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;
if ( 'UTF-8' === get_option( 'blog_charset' ) ) {
/*
* If the page will use UTF-8 encoding, it's safe to print unescaped unicode in
* JSON. Set the following flags:
*
* - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally
* (default is to escape 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 does not specify a character encoding, RFC-8259
* suggests that UTF-8 be used everywhere. It's risky to print unicode if the page
* uses any other encoding.
*
* > JSON text exchanged between systems that are not part of a closed ecosystem
* > MUST be encoded using UTF-8. Previous specifications of JSON have not required
* > the use of UTF-8 when transmitting JSON text. However, the vast majority of
* > JSON- based software implementations have chosen to use the UTF-8 encoding,
* > to the extent that it is the only encoding that achieves interoperability.
*
* @see https://www.rfc-editor.org/rfc/rfc8259.html
*
*/
$json_encode_flags |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS;
}

wp_print_inline_script_tag(
wp_json_encode( $config, JSON_HEX_TAG | JSON_HEX_AMP ),
wp_json_encode( $data, $json_encode_flags ),
array(
'type' => 'application/json',
'id' => 'gb-scriptmodule-data_' . $module_id,
Expand Down

0 comments on commit f9f1610

Please sign in to comment.