Skip to content

Commit a549799

Browse files
committed
Block Processor: Find a delimiter's comment closer by its >.
The closer search used `strpos( $text, '--' )`, which stops at every dash in the JSON attributes, and then `strspn()` over the dash run. Search for `>` instead. No closer can end before the first `>` after the start of the JSON span, so that `>` closes the comment if `--` or `--!` precedes it, and otherwise the search continues after it. The block editor escapes `>` in attributes as `>`, so the first `>` is usually the closer. Scanning theme templates with `next_token()` takes 3% less time; other documents change by 1% to 2%. Adds tests for `>` inside of the JSON attributes. See #66138.
1 parent fb83653 commit a549799

2 files changed

Lines changed: 12 additions & 9 deletions

File tree

‎src/wp-includes/class-wp-block-processor.php‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -986,22 +986,19 @@ public function next_token(): bool {
986986
* The delimiter must also be a single complete HTML comment.
987987
*
988988
* The comment closer, as in {@see self::find_html_comment_end()}, cannot start
989-
* before the JSON span.
989+
* before the JSON span. It ends at the first `>` there which follows `--` or `--!`.
990990
*
991991
* <!-- /wp:core/paragraph {"dropCap":true} /-⃨-⃨>⃨
992992
*/
993-
$closer_at = $json_at;
993+
$closer_at = $json_at - 1;
994994
do {
995-
$dashes_at = strpos( $text, '--', $closer_at );
996-
if ( false === $dashes_at ) {
995+
$closer_at = strpos( $text, '>', $closer_at + 1 );
996+
if ( false === $closer_at ) {
997997
goto incomplete;
998998
}
999999

1000-
$closer_at = $dashes_at + 2 + strspn( $text, '-', $dashes_at + 2 );
1001-
if ( $closer_at < $end && '!' === $text[ $closer_at ] ) {
1002-
++$closer_at;
1003-
}
1004-
} while ( $closer_at >= $end || '>' !== $text[ $closer_at ] );
1000+
$dashes_at = '!' === $text[ $closer_at - 1 ] ? $closer_at - 3 : $closer_at - 2;
1001+
} while ( '-' !== $text[ $dashes_at ] || '-' !== $text[ $dashes_at + 1 ] );
10051002

10061003
$after_comment_end = $closer_at + 1;
10071004

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,12 @@ public static function data_delimiters_and_comment_endings(): array {
723723
'Dash run before a space closer' => array( '<!-- wp:a {"k":"x"} --- -->', array() ),
724724
'Delimiter after a closed comment' => array( '<!-- x --!><!-- wp:a {"k":1} -->', array( 'core/a' ) ),
725725

726+
// Only a `>` after `--` or `--!` ends the comment.
727+
'Greater-than in the attributes' => array( '<!-- wp:a {"k":"a>b"} -->', array( 'core/a' ) ),
728+
'Dash, greater-than in attributes' => array( '<!-- wp:a {"k":"->"} -->', array( 'core/a' ) ),
729+
'Bang, greater-than in attributes' => array( '<!-- wp:a {"k":"-!>"} /-->', array( 'core/a' ) ),
730+
'Comment ends in the attributes' => array( '<!-- wp:a {"k":"-->"} -->', array() ),
731+
726732
// Dashes in the block type do not end the comment.
727733
'Dash run inside the block name' => array( '<!-- wp:a--b -->', array( 'core/a--b' ) ),
728734
'Block type ends in dash runs' => array( '<!-- wp:my--ns/a-- {"k":1} /-->', array( 'my--ns/a--' ) ),

0 commit comments

Comments
 (0)