From a99ec2556e48489620c4e1dfb92128d401dd7e70 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 7 May 2024 17:20:47 +0200 Subject: [PATCH 01/11] Improve Interactivity API store JSON encoding --- .../interactivity-api/class-wp-interactivity-api.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 3db539aae699..41c4fe4c1fdf 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -167,10 +167,15 @@ public function print_client_interactivity_data() { } if ( ! empty( $interactivity_data ) ) { + $json_encode_flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_SLASHES; + if ( str_starts_with( get_option( 'blog_charset' ), 'UTF-' ) ) { + $json_encode_flags |= JSON_UNESCAPED_UNICODE; + } + wp_print_inline_script_tag( wp_json_encode( $interactivity_data, - JSON_HEX_TAG | JSON_HEX_AMP + $json_encode_flags ), array( 'type' => 'application/json', From 8a6d30ff325c8cd0928943030019475fb4ee5cbc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 8 May 2024 14:39:48 +0200 Subject: [PATCH 02/11] Only set unescaped unicode with UTF-8 --- .../interactivity-api/class-wp-interactivity-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 41c4fe4c1fdf..22395df26f57 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -168,7 +168,7 @@ public function print_client_interactivity_data() { if ( ! empty( $interactivity_data ) ) { $json_encode_flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_SLASHES; - if ( str_starts_with( get_option( 'blog_charset' ), 'UTF-' ) ) { + if ( 'UTF-8' === get_option( 'blog_charset' ) ) { $json_encode_flags |= JSON_UNESCAPED_UNICODE; } From 312d6ea77206db63733f537362badd7bb6479e44 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 9 May 2024 10:07:00 +0200 Subject: [PATCH 03/11] Remove JSON_HEX_AMP --- .../interactivity-api/class-wp-interactivity-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 22395df26f57..70afe7014957 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -167,7 +167,7 @@ public function print_client_interactivity_data() { } if ( ! empty( $interactivity_data ) ) { - $json_encode_flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_SLASHES; + $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; if ( 'UTF-8' === get_option( 'blog_charset' ) ) { $json_encode_flags |= JSON_UNESCAPED_UNICODE; } From 3e301171b2b54cb8cf137ba9e760cae9c0eddb33 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 9 May 2024 10:07:23 +0200 Subject: [PATCH 04/11] Add JSON_UNESCAPED_LINE_TERMINATORS --- .../interactivity-api/class-wp-interactivity-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 70afe7014957..95141185b6ca 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -169,7 +169,7 @@ public function print_client_interactivity_data() { if ( ! empty( $interactivity_data ) ) { $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; if ( 'UTF-8' === get_option( 'blog_charset' ) ) { - $json_encode_flags |= JSON_UNESCAPED_UNICODE; + $json_encode_flags |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS; } wp_print_inline_script_tag( From cf29aa660712bc8dc38b4b8cac76fb6718606744 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 9 May 2024 11:21:02 +0200 Subject: [PATCH 05/11] Add comments --- .../class-wp-interactivity-api.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 95141185b6ca..656472c3870a 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -167,8 +167,30 @@ public function print_client_interactivity_data() { } if ( ! empty( $interactivity_data ) ) { + + /* + * This data will be printed as JSON inside a script tag: + * + * 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 /. + * + * @see https://www.php.net/manual/en/json.constants.php + */ $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; if ( 'UTF-8' === get_option( 'blog_charset' ) ) { + /* + * If the page uses the UTF-8 charset unicode does not need to be escaped. + * + * - 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. + */ $json_encode_flags |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS; } From 76c7a5e594d471593873ed828fd36ae96cde60e3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 9 May 2024 12:03:43 +0200 Subject: [PATCH 06/11] Smaller config in test --- .../interactivity-api/wpInteractivityAPI.php | 77 ++++++++++++++++++- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php index ffcc8087acf3..1a9932693a9b 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php @@ -27,6 +27,17 @@ public function set_up() { $this->interactivity = new WP_Interactivity_API(); } + /** + * Tear down. + */ + public function tear_down() { + remove_filter( 'pre_option_blog_charset', array( $this, 'charset_iso_8859_1' ) ); + } + + public function charset_iso_8859_1() { + return 'iso-8859-1'; + } + /** * Tests that the state and config methods return an empty array at the * beginning. @@ -349,20 +360,78 @@ public function test_config_printed_correctly_with_nested_empty_array() { * properly escaped. * * @ticket 60356 + * @ticket 61170 * * @covers ::state * @covers ::config * @covers ::print_client_interactivity_data */ public function test_state_and_config_escape_special_characters() { - $this->interactivity->state( 'myPlugin', array( 'amps' => 'http://site.test/?foo=1&baz=2' ) ); - $this->interactivity->config( 'myPlugin', array( 'tags' => 'Tags: