From 655c21bbeaa72b4a05fcb1aef95803aecc1464d0 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Wed, 24 Apr 2019 21:39:53 +0000 Subject: [PATCH] Fix parsing of inner blocks when auto-generating an excerpt. Helps to prevent cases where dynamic inner blocks may cause an infinite loop if trying to auto-generate an excerpt. Props desrosj, pento, gziolo, azaozz. Fixes #46133. Built from https://develop.svn.wordpress.org/trunk@45265 git-svn-id: http://core.svn.wordpress.org/trunk@45074 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/blocks.php | 51 ++++++++++++++++++++++++++++++++++++++--- wp-includes/version.php | 2 +- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/wp-includes/blocks.php b/wp-includes/blocks.php index ba9fc4f344..169e4b3c25 100644 --- a/wp-includes/blocks.php +++ b/wp-includes/blocks.php @@ -125,10 +125,9 @@ function get_dynamic_block_names() { * @return string The parsed and filtered content. */ function excerpt_remove_blocks( $content ) { - $allowed_blocks = array( + $allowed_inner_blocks = array( // Classic blocks have their blockName set to null. null, - 'core/columns', 'core/freeform', 'core/heading', 'core/html', @@ -141,6 +140,9 @@ function excerpt_remove_blocks( $content ) { 'core/table', 'core/verse', ); + + $allowed_blocks = array_merge( $allowed_inner_blocks, array( 'core/columns' ) ); + /** * Filters the list of blocks that can contribute to the excerpt. * @@ -154,12 +156,55 @@ function excerpt_remove_blocks( $content ) { $allowed_blocks = apply_filters( 'excerpt_allowed_blocks', $allowed_blocks ); $blocks = parse_blocks( $content ); $output = ''; + foreach ( $blocks as $block ) { if ( in_array( $block['blockName'], $allowed_blocks, true ) ) { + if ( ! empty( $block['innerBlocks'] ) ) { + if ( 'core/columns' === $block['blockName'] ) { + $output .= _excerpt_render_inner_columns_blocks( $block, $allowed_inner_blocks ); + continue; + } + + // Skip the block if it has disallowed or nested inner blocks. + foreach ( $block['innerBlocks'] as $inner_block ) { + if ( + ! in_array( $inner_block['blockName'], $allowed_inner_blocks, true ) || + ! empty( $inner_block['innerBlocks'] ) + ) { + continue 2; + } + } + } + $output .= render_block( $block ); } } - return $output; + + return $output; +} + +/** + * Render inner blocks from the `core/columns` block for generating an excerpt. + * + * @since 5.2.0 + * @access private + * + * @param array $columns The parsed columns block. + * @param array $allowed_blocks The list of allowed inner blocks. + * @return string The rendered inner blocks. + */ +function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) { + $output = ''; + + foreach ( $columns['innerBlocks'] as $column ) { + foreach ( $column['innerBlocks'] as $inner_block ) { + if ( in_array( $inner_block['blockName'], $allowed_blocks, true ) && empty( $inner_block['innerBlocks'] ) ) { + $output .= render_block( $inner_block ); + } + } + } + + return $output; } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index 0ff9e9fde6..683e8e0297 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.2-beta3-45264'; +$wp_version = '5.2-beta3-45265'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.