Commit 00025498a9 for wordpress.org
commit 00025498a9a5bd4d5c24b53f60ae0c3f710172c4
Author: dmsnell <dmsnell@git.wordpress.org>
Date: Fri Oct 30 20:38:55 2026 +0000
Blocks: Fix duplicated content when implicitly closing a final open block
When a fix was recently applied to the block parser for implicitly closing open blocks that remain open at the end of a document, a mistake was made when collecting HTML spans preceding the still-open blocks. This led to duplicated content in documents missing expected closing delimiters.
This patch adjusts the implict closing algorithm to properly detect those HTML spans.
Developed in: https://github.com/WordPress/wordpress-develop/pull/15197
Discussed in: https://core.trac.wordpress.org/ticket/66138
Follow-up to r64996.
Props chihsuan, dmsnell.
See #66138.
Built from https://develop.svn.wordpress.org/trunk@65090
git-svn-id: http://core.svn.wordpress.org/trunk@64240 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/class-wp-block-parser.php b/wp-includes/class-wp-block-parser.php
index 5adc9d95e6..06342fc5ac 100644
--- a/wp-includes/class-wp-block-parser.php
+++ b/wp-includes/class-wp-block-parser.php
@@ -395,40 +395,55 @@ class WP_Block_Parser {
* @since 7.2.0
*/
public function implicitly_close_and_add_all_open_blocks(): void {
- $implicitly_closed = null;
- $last_freeform = null;
-
+ $last_closed_block = null;
+ $last_opener_at = strlen( $this->document );
+ $last_leading_html = null;
+
+ /**
+ * There is a stack of open blocks, starting with a top-level block,
+ * and where each successive item in the stack is a child of that block.
+ * There are also spans of HTML content between the block delimiters.
+ *
+ * As the stack is collapsed, any HTML segments within that block must
+ * be collected into it, before closing and appending to its parent’s
+ * inner blocks array.
+ */
while ( null !== ( $stack_top = array_pop( $this->stack ) ) ) {
- if ( isset( $last_freeform ) ) {
- $html = substr( $this->document, $stack_top->prev_offset, $last_freeform[1] - $stack_top->prev_offset );
- } else {
- $html = substr( $this->document, $stack_top->prev_offset );
- }
+ /*
+ * Since there is no open inner block on the top-most block on the stack,
+ * the first iteration’s remaining HTML span will be from the last `prev_offset`
+ * until the end of the document. For each containing parent, it will run from
+ * the `prev_offset` until the opening of the block that was just closed.
+ */
+ $html_length = $last_opener_at - $stack_top->prev_offset;
+ if ( 0 !== $html_length ) {
+ $html = substr( $this->document, $stack_top->prev_offset, $html_length );
- if ( '' !== $html ) {
$stack_top->block->innerHTML .= $html;
$stack_top->block->innerContent[] = $html;
}
- // Trap potential leading freeform content for the final output.
- $last_freeform = array( $stack_top->leading_html_start ?? 0, $stack_top->token_start );
-
- if ( isset( $implicitly_closed ) ) {
+ if ( isset( $last_closed_block ) ) {
$stack_top->block->innerContent[] = null;
- $stack_top->block->innerBlocks[] = (array) $implicitly_closed;
+ $stack_top->block->innerBlocks[] = (array) $last_closed_block;
}
- $implicitly_closed = $stack_top->block;
+ $last_closed_block = $stack_top->block;
+ $last_opener_at = $stack_top->token_start;
+ $last_leading_html = $stack_top->leading_html_start;
}
- if ( isset( $last_freeform ) && $last_freeform[1] > $last_freeform[0] ) {
- $html = substr( $this->document, $last_freeform[0], $last_freeform[1] - $last_freeform[0] );
+ // Collect any HTML preceding the outermost open block.
+ if ( isset( $last_leading_html ) && $last_opener_at > $last_leading_html ) {
+ $html = substr( $this->document, $last_leading_html, $last_opener_at - $last_leading_html );
$this->output[] = (array) $this->freeform( $html );
}
- if ( isset( $implicitly_closed ) ) {
- $this->output[] = (array) $implicitly_closed;
+ if ( isset( $last_closed_block ) ) {
+ $this->output[] = (array) $last_closed_block;
}
+
+ $this->offset = strlen( $this->document );
}
}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 03219aaca9..47576d75a5 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-beta3-65089';
+$wp_version = '7.2-beta3-65090';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.