Commit 71175c0d40 for wordpress.org
commit 71175c0d407df2fafd4dfe8fbd25eaec783498d1
Author: jonsurrell <jonsurrell@git.wordpress.org>
Date: Thu Sep 24 05:54:49 2026 +0000
Block Processor: Ensure block delimiters align with single HTML comments.
Developed in: https://github.com/WordPress/wordpress-develop/pull/13680
Props jonsurrell, dmsnell.
See #66138.
Built from https://develop.svn.wordpress.org/trunk@63913
git-svn-id: http://core.svn.wordpress.org/trunk@63082 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/class-wp-block-processor.php b/wp-includes/class-wp-block-processor.php
index cc86519cef..b62bb1c511 100644
--- a/wp-includes/class-wp-block-processor.php
+++ b/wp-includes/class-wp-block-processor.php
@@ -979,13 +979,32 @@ class WP_Block_Processor {
* This also matches the behavior in the official block parser,
* even though it allows for matching invalid JSON content.
*
+ * The delimiter must also be a single complete HTML comment.
+ *
* <!-- /wp:core/paragraph {"dropCap":true} /-⃨-⃨>⃨
*/
- $comment_closing_at = strpos( $text, '-->', $json_at );
- if ( false === $comment_closing_at ) {
+ $after_comment_end = $this->find_html_comment_end( $comment_opening_at, $end );
+
+ /*
+ * The reported end of the comment could be after the end of the document if
+ * no actual end was found, so differentiate a comment ending at the end of
+ * the document from documents with missing comment ends.
+ */
+ if ( $after_comment_end >= $end && ! str_ends_with( $text, '-->' ) && ! str_ends_with( $text, '--!>' ) ) {
goto incomplete;
}
+ /*
+ * Only normative comment closers are recognized block delimiters,
+ * so skip past any HTML comments ending in `--!>`.
+ */
+ if ( '!' === $text[ $after_comment_end - 2 ] ) {
+ $at = $after_comment_end;
+ continue;
+ }
+
+ $comment_closing_at = $after_comment_end - 3;
+
// <!-- /wp:core/paragraph {"dropCap":true} /⃨-->
if ( '/' === $text[ $comment_closing_at - 1 ] ) {
$has_void_flag = true;
@@ -1007,7 +1026,7 @@ class WP_Block_Processor {
break;
}
- $at = $this->find_html_comment_end( $comment_opening_at, $end );
+ $at = $after_comment_end;
continue;
}
@@ -1015,6 +1034,7 @@ class WP_Block_Processor {
* There's JSON, so attempt to find its boundary.
*
* @todo It’s likely faster to scan forward instead of in reverse.
+ * @todo Skip ahead with `strcspn()` and decide only on syntax characters.
*
* <!-- /wp:core/paragraph {"dropCap":true}⃨ ⃨/-->
*/
@@ -1036,7 +1056,7 @@ class WP_Block_Processor {
break 2;
default:
- ++$at;
+ $at = $after_comment_end;
continue 3;
}
}
@@ -1046,7 +1066,7 @@ class WP_Block_Processor {
* mandatory whitespace is missing.
*/
if ( 0 === $json_length || 0 === $after_json_whitespace_length ) {
- $at = $this->find_html_comment_end( $comment_opening_at, $end );
+ $at = $after_comment_end;
continue;
}
@@ -1057,6 +1077,19 @@ class WP_Block_Processor {
// The end of the document was reached without a match.
if ( self::MATCHED !== $this->state ) {
+ // Stop at top-level free-form HTML at the end of the document.
+ if ( $after_prev_delimiter < $end ) {
+ $this->state = self::HTML_SPAN;
+ $this->after_previous_delimiter = $after_prev_delimiter;
+ $this->matched_delimiter_at = $end;
+ $this->matched_delimiter_length = 0;
+ $this->open_blocks_at[] = $after_prev_delimiter;
+ $this->open_blocks_length[] = 0;
+ $this->was_void = true;
+
+ return true;
+ }
+
$this->state = self::COMPLETE;
return false;
}
@@ -1336,7 +1369,7 @@ class WP_Block_Processor {
$comment_starting_at + 2 + $span_of_dashes < $search_end &&
'>' === $text[ $comment_starting_at + 2 + $span_of_dashes ]
) {
- return $comment_starting_at + $span_of_dashes + 1;
+ return $comment_starting_at + 2 + $span_of_dashes + 1;
}
// Otherwise, there are other characters inside the comment, find the first `-->` or `--!>`.
diff --git a/wp-includes/version.php b/wp-includes/version.php
index fc22223180..8dedab56e4 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-63912';
+$wp_version = '7.2-alpha-63913';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.