Skip to content

Commit aee8aae

Browse files
committed
Merge branch 'trunk' into add-ability-versioning
2 parents bc3b776 + 8867703 commit aee8aae

File tree

4 files changed

+76
-24
lines changed

4 files changed

+76
-24
lines changed

src/js/_enqueues/wp/sanitize.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,25 @@
2323
* @return {string} Stripped text.
2424
*/
2525
stripTags: function( text ) {
26-
let _text = text || '';
26+
const domParser = new DOMParser();
27+
const htmlDocument = domParser.parseFromString(
28+
text,
29+
'text/html'
30+
);
2731

28-
// Do the search-replace until there is nothing to be replaced.
29-
do {
30-
// Keep pre-replace text for comparison.
31-
text = _text;
32-
33-
// Do the replacement.
34-
_text = text
35-
.replace( /<!--[\s\S]*?(-->|$)/g, '' )
36-
.replace( /<(script|style)[^>]*>[\s\S]*?(<\/\1>|$)/ig, '' )
37-
.replace( /<\/?[a-z][\s\S]*?(>|$)/ig, '' );
38-
} while ( _text !== text );
32+
/*
33+
* The following self-assignment appears to be a no-op, but it isn't.
34+
* It enforces the escaping. Reading the `innerText` property decodes
35+
* character references, returning a raw string. When written, however,
36+
* the text is re-escaped to ensure that the rendered text replicates
37+
* what it's given.
38+
*
39+
* See <https://github.com/WordPress/wordpress-develop/pull/10536#discussion_r2550615378>.
40+
*/
41+
htmlDocument.body.innerText = htmlDocument.body.innerText;
3942

4043
// Return the text with stripped tags.
41-
return _text;
44+
return htmlDocument.body.innerHTML;
4245
},
4346

4447
/**

src/wp-includes/html-api/class-wp-html-tag-processor.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,10 +2342,12 @@ private function class_name_updates_to_attributes_updates(): void {
23422342
}
23432343

23442344
if ( false === $existing_class && isset( $this->attributes['class'] ) ) {
2345-
$existing_class = substr(
2346-
$this->html,
2347-
$this->attributes['class']->value_starts_at,
2348-
$this->attributes['class']->value_length
2345+
$existing_class = WP_HTML_Decoder::decode_attribute(
2346+
substr(
2347+
$this->html,
2348+
$this->attributes['class']->value_starts_at,
2349+
$this->attributes['class']->value_length
2350+
)
23492351
);
23502352
}
23512353

tests/phpunit/tests/block-processor/wpBlockProcessor-BlockProcessing.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,34 @@ public function test_get_depth() {
4949
}
5050

5151
$processor = new WP_Block_Processor( $html );
52-
$n = new NumberFormatter( 'en-US', NumberFormatter::ORDINAL );
5352

5453
for ( $i = 0; $i < $max_depth; $i++ ) {
54+
$nth = $i + 1;
55+
5556
$this->assertTrue(
5657
$processor->next_delimiter(),
57-
"Should have found {$n->format( $i + 1 )} opening delimiter: check test setup."
58+
"Should have found opening delimiter #{$nth}: check test setup."
5859
);
5960

6061
$this->assertSame(
6162
$i + 1,
6263
$processor->get_depth(),
63-
"Should have identified the proper depth of the {$n->format( $i + 1 )} opening delimiter."
64+
"Should have identified the proper depth of opening delimiter #{$nth}."
6465
);
6566
}
6667

6768
for ( $i = 0; $i < $max_depth; $i++ ) {
69+
$nth = $i + 1;
70+
6871
$this->assertTrue(
6972
$processor->next_delimiter(),
70-
"Should have found {$n->format( $i + 1 )} closing delimiter: check test setup."
73+
"Should have found closing delimiter #{$nth}: check test setup."
7174
);
7275

7376
$this->assertSame(
7477
$max_depth - $i - 1,
7578
$processor->get_depth(),
76-
"Should have identified the proper depth of the {$n->format( $i + 1 )} closing delimiter."
79+
"Should have identified the proper depth of closing delimiter #{$nth}."
7780
);
7881
}
7982
}

tests/phpunit/tests/html-api/wpHtmlTagProcessor.php

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,11 +2887,11 @@ public static function data_updating_attributes_in_malformed_html() {
28872887
),
28882888
'HTML tag opening inside attribute value' => array(
28892889
'input' => '<pre id="<code" class="wp-block-code <code is poetry&gt;"><code>This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
2890-
'expected' => '<pre foo="bar" id="<code" class="wp-block-code &lt;code is poetry&amp;gt; firstTag"><code class="secondTag">This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
2890+
'expected' => '<pre foo="bar" id="<code" class="wp-block-code &lt;code is poetry&gt; firstTag"><code class="secondTag">This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
28912891
),
28922892
'HTML tag brackets in attribute values and data markup' => array(
28932893
'input' => '<pre id="<code-&gt;-block-&gt;" class="wp-block-code <code is poetry&gt;"><code>This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
2894-
'expected' => '<pre foo="bar" id="<code-&gt;-block-&gt;" class="wp-block-code &lt;code is poetry&amp;gt; firstTag"><code class="secondTag">This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
2894+
'expected' => '<pre foo="bar" id="<code-&gt;-block-&gt;" class="wp-block-code &lt;code is poetry&gt; firstTag"><code class="secondTag">This &lt;is> a &lt;strong is="true">thing.</code></pre><span>test</span>',
28952895
),
28962896
'Single and double quotes in attribute value' => array(
28972897
'input' => '<p title="Demonstrating how to use single quote (\') and double quote (&quot;)"><span>test</span>',
@@ -3028,6 +3028,50 @@ public static function data_updating_attributes_in_malformed_html() {
30283028
);
30293029
}
30303030

3031+
/**
3032+
* @ticket 64340
3033+
*/
3034+
public function test_class_changes_produce_correct_html() {
3035+
$processor = new WP_HTML_Tag_Processor( '<div class="&amp;">' );
3036+
$processor->next_tag();
3037+
3038+
$processor->add_class( '"' );
3039+
$processor->get_updated_html();
3040+
3041+
$processor->add_class( 'OK' );
3042+
$processor->get_updated_html();
3043+
3044+
$this->assertTrue( $processor->has_class( '&' ), 'Missing expected "&" class.' );
3045+
$this->assertTrue( $processor->has_class( '"' ), 'Missing expected \'"\' class.' );
3046+
$this->assertTrue( $processor->has_class( 'OK' ), 'Missing expected "OK" class.' );
3047+
3048+
$expected = '<div class="&amp; &quot; OK">';
3049+
$this->assertEqualHTML(
3050+
$expected,
3051+
$processor->get_updated_html(),
3052+
'<body>',
3053+
'HTML was not correctly updated after adding classes.'
3054+
);
3055+
3056+
$processor->remove_class( '&' );
3057+
$processor->get_updated_html();
3058+
3059+
$processor->remove_class( '"' );
3060+
$processor->get_updated_html();
3061+
3062+
$this->assertFalse( $processor->has_class( '&' ) );
3063+
$this->assertFalse( $processor->has_class( '"' ) );
3064+
$this->assertTrue( $processor->has_class( 'OK' ) );
3065+
3066+
$expected = '<div class="OK">';
3067+
$this->assertEqualHTML(
3068+
$expected,
3069+
$processor->get_updated_html(),
3070+
'<body>',
3071+
'HTML was not correctly updated after removing classes.'
3072+
);
3073+
}
3074+
30313075
/**
30323076
* @covers WP_HTML_Tag_Processor::next_tag
30333077
*/

0 commit comments

Comments
 (0)