Script Loader: Harden removal of script tag wrappers.

* Add `wp_remove_surrounding_empty_script_tags()` to more precisely remove script tag wrappers and warn when doing it wrong.
* Add clarifying comments for XML escaping logic in `wp_get_inline_script_tag()`.
* Leverage `WP_HTML_Tag_Processor` in `test_remove_frameless_preview_messenger_channel`.
* Reuse `assertEqualMarkup` in `test_blocking_dependent_with_delayed_dependency`.
* Normalize whitespace in `parse_markup_fragment` for `assertEqualMarkup`.

Follow-up to [56687].
Props dmsnell, westonruter, flixos90.
See #58664.


git-svn-id: https://develop.svn.wordpress.org/trunk@56748 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Weston Ruter
2023-09-29 19:45:53 +00:00
parent 4baf0a1eda
commit 8c0adc93df
12 changed files with 193 additions and 20 deletions
+2 -2
View File
@@ -3135,8 +3135,8 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase {
$manager = new WP_Customize_Manager( array( 'messenger_channel' => 'preview-0' ) );
ob_start();
$manager->remove_frameless_preview_messenger_channel();
$output = ob_get_clean();
$this->assertStringContainsString( '<script', $output );
$processor = new WP_HTML_Tag_Processor( ob_get_clean() );
$this->assertTrue( $processor->next_tag( 'script' ), 'Failed to find expected SCRIPT element in output.' );
}
/**
+14 -2
View File
@@ -260,8 +260,11 @@ JS;
wp_enqueue_script( 'main-script-a3', '/main-script-a3.js', array(), null, compact( 'strategy' ) );
wp_enqueue_script( 'dependent-script-a3', '/dependent-script-a3.js', array( 'main-script-a3' ), null );
$output = get_echo( 'wp_print_scripts' );
$expected = str_replace( "'", '"', "<script type='text/javascript' src='/main-script-a3.js' id='main-script-a3-js' data-wp-strategy='{$strategy}'></script>" );
$this->assertStringContainsString( $expected, $output, 'Blocking dependents must force delayed dependencies to become blocking.' );
$expected = <<<JS
<script type='text/javascript' src='/main-script-a3.js' id='main-script-a3-js' data-wp-strategy='{$strategy}'></script>
<script id="dependent-script-a3-js" src="/dependent-script-a3.js" type="text/javascript"></script>
JS;
$this->assertEqualMarkup( $expected, $output, 'Blocking dependents must force delayed dependencies to become blocking.' );
}
/**
@@ -2997,6 +3000,15 @@ HTML
}
}
// Normalize other whitespace nodes.
$xpath = new DOMXPath( $dom );
foreach ( $xpath->query( '//text()' ) as $node ) {
/** @var DOMText $node */
if ( preg_match( '/^\s+$/', $node->nodeValue ) ) {
$node->nodeValue = ' ';
}
}
return $dom;
}
@@ -0,0 +1,78 @@
<?php
/**
* Test wp_remove_surrounding_empty_script_tags().
*
* @group dependencies
* @group scripts
* @ticket 58664
* @covers ::wp_remove_surrounding_empty_script_tags
*/
class Tests_Functions_wpRemoveSurroundingEmptyScriptTags extends WP_UnitTestCase {
/**
* Data provider for test.
*
* @return array
*/
public function get_data_to_test_wp_remove_surrounding_empty_script_tags() {
$error_js = 'console.error("Function wp_remove_surrounding_empty_script_tags() used incorrectly in PHP. Expected string to start with script tag (without attributes) and end with script tag, with optional whitespace.")';
return array(
'basic_case' => array(
'<script>alert("hello")</script>',
'alert("hello")',
false,
),
'BASIC_CASE' => array(
'<SCRIPT>alert("hello")</SCRIPT>',
'alert("hello")',
false,
),
'whitespace_basic_case' => array(
' <script>alert("hello")</script> ',
'alert("hello")',
false,
),
'missing_tags' => array(
'alert("hello")',
$error_js,
true,
),
'missing_start_tag' => array(
'alert("hello")</script>',
$error_js,
true,
),
'missing_end_tag' => array(
'<script>alert("hello")',
$error_js,
true,
),
'erroneous attributes' => array(
'<script type="text/javascript">alert("hello")</script>',
$error_js,
true,
),
);
}
/**
* Test scenarios for wp_remove_surrounding_empty_script_tags().
*
* @dataProvider get_data_to_test_wp_remove_surrounding_empty_script_tags
*
* @param string $input Input.
* @param string $expected Expected.
* @param bool $expect_doing_it_wrong Whether input is _doing_it_wrong().
*/
public function test_wp_remove_surrounding_empty_script_tags( $input, $expected, $expect_doing_it_wrong ) {
if ( $expect_doing_it_wrong ) {
$this->setExpectedIncorrectUsage( 'wp_remove_surrounding_empty_script_tags' );
}
$this->assertSame(
$expected,
wp_remove_surrounding_empty_script_tags( $input )
);
}
}