diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index 2bd9f2dfbf050..96fc9c4eb6149 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -766,7 +766,7 @@ function block_editor_rest_api_preload( array $preload_paths, $block_editor_cont 'wp-api-fetch', sprintf( 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', - wp_json_encode( $preload_data ) + wp_json_encode( $preload_data, JSON_UNESCAPED_SLASHES ) ), 'after' ); diff --git a/src/wp-includes/functions.wp-scripts.php b/src/wp-includes/functions.wp-scripts.php index 1be1822aa7c3d..fced2ebaf9978 100644 --- a/src/wp-includes/functions.wp-scripts.php +++ b/src/wp-includes/functions.wp-scripts.php @@ -130,18 +130,42 @@ function wp_print_scripts( $handles = false ) { function wp_add_inline_script( $handle, $data, $position = 'after' ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); - if ( false !== stripos( $data, '' ) ) { - _doing_it_wrong( - __FUNCTION__, - sprintf( - /* translators: 1: #is', '$1', $data ) ); + /* + * Check whether the script data appears to be enclosed in an HTML ` could close the SCRIPT element prematurely. + * + * The text `', wp_sanitize_script_attributes( $attributes ) ); + $processor = new WP_HTML_Tag_Processor( $script_tag ); + if ( $processor->next_tag( 'SCRIPT' ) && $processor->set_modifiable_text( $data ) ) { + return $processor->get_updated_html() . "\n"; + } + return sprintf( "%s\n", wp_sanitize_script_attributes( $attributes ), $data ); } diff --git a/tests/phpunit/tests/blocks/editor.php b/tests/phpunit/tests/blocks/editor.php index 838137fa76f0d..71d28e62a4e6f 100644 --- a/tests/phpunit/tests/blocks/editor.php +++ b/tests/phpunit/tests/blocks/editor.php @@ -9,7 +9,6 @@ * @group blocks */ class Tests_Blocks_Editor extends WP_UnitTestCase { - /** * Sets up each test method. */ @@ -631,8 +630,8 @@ function filter_add_preload_paths( $preload_paths, WP_Block_Editor_Context $cont $after = implode( '', wp_scripts()->registered['wp-api-fetch']->extra['after'] ); $this->assertStringContainsString( 'wp.apiFetch.createPreloadingMiddleware', $after ); - $this->assertStringContainsString( '"\/wp\/v2\/blocks"', $after ); - $this->assertStringContainsString( '"\/wp\/v2\/types"', $after ); + $this->assertStringContainsString( '"/wp/v2/blocks"', $after ); + $this->assertStringContainsString( '"/wp/v2/types"', $after ); } /** @@ -697,11 +696,11 @@ public function data_block_editor_rest_api_preload_adds_missing_leading_slash() return array( 'a string without a slash' => array( 'preload_paths' => array( 'wp/v2/blocks' ), - 'expected' => '\/wp\/v2\/blocks', + 'expected' => '/wp/v2/blocks', ), 'a string with a slash' => array( 'preload_paths' => array( '/wp/v2/blocks' ), - 'expected' => '\/wp\/v2\/blocks', + 'expected' => '/wp/v2/blocks', ), 'a string starting with a question mark' => array( 'preload_paths' => array( '?context=edit' ), @@ -709,16 +708,63 @@ public function data_block_editor_rest_api_preload_adds_missing_leading_slash() ), 'an array with a string without a slash' => array( 'preload_paths' => array( array( 'wp/v2/blocks', 'OPTIONS' ) ), - 'expected' => '\/wp\/v2\/blocks', + 'expected' => '/wp/v2/blocks', ), 'an array with a string with a slash' => array( 'preload_paths' => array( array( '/wp/v2/blocks', 'OPTIONS' ) ), - 'expected' => '\/wp\/v2\/blocks', + 'expected' => '/wp/v2/blocks', ), 'an array with a string starting with a question mark' => array( 'preload_paths' => array( array( '?context=edit', 'OPTIONS' ) ), - 'expected' => '\/?context=edit', + 'expected' => '/?context=edit', ), ); } + + /** + * @ticket 62797 + * + * @covers ::block_editor_rest_api_preload + * + * Some valid JSON-encoded data is dangerous to embed in HTML without appropriate + * escaping. This test includes prints an example of such data that would prevent + * the enclosing `' => array( '', 'Just a ' ), - 'SCRIPT with ' => array( '', 'beforeafter' ), + 'Comment with -->' => array( '', 'Comments end in -->' ), + 'Comment with --!>' => array( '', 'Invalid but legitimate comments end in --!>' ), + 'Non-JS SCRIPT with ', '