Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 18 months ago

#56941 closed defect (bug) (worksforme)

Fatal error produced by block using closure as render_callback

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

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
4 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
4 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
4 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
4 years ago

  • Keywords reporter-feedback added
  • Milestone Awaiting Review → 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 4 years ago by audrasjb (previous) (diff)

#5 @audrasjb
4 years ago

  • Keywords reporter-feedback removed
  • Milestone 6.1
  • Resolution → worksforme
  • Severity blocker → normal
  • Status assigned → closed
  • Version 6.1

Closing as per comment 3 :)

#6 @Takahashi_Fumiki
18 months 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 18 months ago by Takahashi_Fumiki (previous) (diff)
Note: See TracTickets for help on using tickets.