Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 16 hours ago

#56941 closed defect (bug) (worksforme)

Fatal error produced by block using closure as render_callback

Reported by: andrewleap's profile andrewleap Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Themes Keywords:
Focuses: Cc:

Description

The following code causes site to blow up on front and in post editor

register_block_type(
	__DIR__,
	array(
                                     // attempted to serialize closure      
		'render_callback' => function( $attributes, $content, $block ){}
	)
);


Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in /app/wp-includes/block-supports/elements.php...

Change History (6)

#1 follow-up: @wildworks
2 years ago

I could not reproduce it in either WordPress 6.0 or 6.1-RC6. Did it work correctly in WordPress 6.0?

Here is my test procedure:

  • Run npx @wordpress/create-block test-block directly under the plugin directory
  • Update test-block.php as follows:
function create_block_test_block_block_init() {
	register_block_type(
		__DIR__ . '/build',
		array(
			'render_callback' => function( $attributes, $content, $block ) {
				return 'rendered';
			},
		)
	);
}
add_action( 'init', 'create_block_test_block_block_init' );
  • Insert the block into the editor and save it
  • Confirm that no errors occur in both the editor and the front end

#2 @audrasjb
2 years ago

@andrewleap thanks for the ticket!

Could you please provide more info about the WordPress version you used when you produced this issue? Thanks :)

#3 in reply to: ↑ 1 @andrewleap
2 years ago

Apologies, This was my mistake. I was panicking as the new version is being released imminently .

The culprit was actually this in my theme:

/**
 * Add a reference to block parent in render function.
 *
 * @param array $parsed_block Block data.
 */
function xd_append_parent_block_data( $parsed_block ) {
	$block = new WP_Block( $parsed_block );
	foreach ( $parsed_block['innerBlocks'] as &$inner_block ) {
		$inner_block['parent'] = array(
			'name'  => $block->name,
			'props' => $block->attributes,
			'block' => $block,
		);
	}
	return $parsed_block;
}

add_filter( 'render_block_data', 'xd_append_parent_block_data' );

We add a reference to the parent block in the block data as this allows us to contextually change the output in the render function. That parent block will also have a closure for its render callback function. Of Course, the block serialization that was recently added will not play nice when trying to serialize a callback.

<?php
function wp_get_elements_class_name( $block ) {
        return 'wp-elements-' . md5( serialize( $block ) );
}

We can fix this with update to our plugin. Thanks for taking the time to look at this.

#4 @audrasjb
2 years ago

  • Keywords reporter-feedback added
  • Milestone changed from Awaiting Review to 6.1

Moving to milestone 6.1 for better visibility, while we're waiting for reporter feedback.

(if the issue is confirmed, this ticket will probably move to 6.1.1 though)

Last edited 2 years ago by audrasjb (previous) (diff)

#5 @audrasjb
2 years ago

  • Keywords reporter-feedback removed
  • Milestone 6.1 deleted
  • Resolution set to worksforme
  • Severity changed from blocker to normal
  • Status changed from assigned to closed
  • Version 6.1 deleted

Closing as per comment 3 :)

#6 @Takahashi_Fumiki
21 hours ago

This issue appears to have already been closed by the plugin author @andrewleap , but there are cases where other plugins consider it to be a WordPress issue.

https://github.com/Yoast/wordpress-seo/issues/22181

The above is a case where the plugin utilizes Object Cache, but since the WP_Taxonomy object can specify a closure in meta_box_cb property, it may eventually be serialized and cause an error depending on the environment. For reference, I have included a cross-reference.

  • WordPress core should not serialize arrays that may contain closure functions.
  • It is necessary to check in advance whether the array has a callable property. If it does, it should not be serialized.

I think it might be a good idea to have a function like wp_serialize.

Last edited 16 hours ago by Takahashi_Fumiki (previous) (diff)
Note: See TracTickets for help on using tickets.