Make WordPress Core

Opened 6 years ago

Last modified 20 months ago

#31496 new defect (bug)

register_uninstall_hook tries to serialize anonymous functions

Reported by: giuseppe.mazzapica Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Plugins Keywords:
Focuses: Cc:


register_uninstall_hook saves uninstall callback in database.

If one passes a closure as uninstall callback WordPress tries to serialize it, causing a Serialization of Closure Exception.

register_uninstall_hook already ensures that array callbacks are not allowed if first element of the array is an object (see #13786).

The complete check should be something like:

if ( is_object( $callback ) || ( is_array( $callback ) && is_object( $callback[0] ) ) ) {

Checking for is_object also prevents usage of invokable objects.

Change History (3)

#1 follow-up: @dd32
6 years ago

Could we simply reject anything that isn't a string?

#2 in reply to: ↑ 1 @giuseppe.mazzapica
6 years ago

Replying to dd32:

Could we simply reject anything that isn't a string?

Well, static methods in array should be fine. We can make the check opt-in instead of opt-out:

function register_uninstall_hook( $file, $callback ) {
    if ( is_string( $callback ) || ( is_array( $callback ) && is_string( $callback[0] ) ) ) {
        $uninstallable_plugins = (array) get_option('uninstall_plugins');
        $uninstallable_plugins[plugin_basename($file)] = $callback;
        update_option('uninstall_plugins', $uninstallable_plugins);
    _doing_it_wrong( __FUNCTION__, __( 'Only a static class method or function...' ), '3.1' );

If it makes any difference...

#3 @crankycyclops
5 years ago

Just curious, has any progress been made on this? I'm running into the same issue and have had to significantly alter the design of my object oriented plugin to get my code to work. Closure support for register_uninstall_hook() would be very nice :)

Thank you!

Note: See TracTickets for help on using tickets.