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.