WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 19 months ago

#16562 closed defect (bug) (fixed)

sometimes deactivation of plugin deactivates another

Reported by: Ghost_ufa Owned by: nacin
Milestone: 3.5 Priority: normal
Severity: major Version: 3.1
Component: General Keywords: has-patch
Focuses: Cc:

Description

in some cases of plugin's mailfunctions serialized list of active plugins has gaps in index - ex. 14 15 17 18
Current WP realisation don't correct it and can't work correctly, and occures deactivation of incorrect plugin.

resolution:

file wp-admin/includes/plugin.php
function deactivate_plugins

is:

                if ( $network_wide ) {
                        $do_network = true;
                        unset( $network_current[ $plugin ] );
                } else {
                        $key = array_search( $plugin, $current );
                        if ( false !== $key ) {
                                $do_blog = true;
                                array_splice( $current, $key, 1 );
                        }
                }

should be:
unset( $network_current[ $key ] );

instead of
array_splice( $current, $key, 1 );

And after loop, just before "if ( $do_blog )", add index renumbering like this:

        $i=0;       $new_current=array();
        foreach ( (array) $current as $cur ) $new_current[$i++]=$cur;
        $current=$new_current;

Attachments (2)

16562.patch (408 bytes) - added by hakre 3 years ago.
16562.2.patch (786 bytes) - added by hakre 3 years ago.
Just in case some argu that get_option() might return anything else than an array.

Download all attachments as: .zip

Change History (7)

comment:1 dd323 years ago

can you post an example of a damaged option, or any explanation of how you've come across this?

comment:2 dd323 years ago

  • Keywords reporter-feedback added; plugin deactivation miss removed

hakre3 years ago

comment:3 hakre3 years ago

  • Keywords has-patch added

Nice find.

For a little explanation what is going on, basically it's using a key value as a numerical offset:

  • array_search() returns the key, not the offset of an array.
  • array_splice() is using a numerical offset which must not be the numerical value of $key.
  • array_splice() is used to remove a single element only, it just does what unset() is used for.

Trivial to patch.

In case running into that, its not obvious what was going on. Thanks for reporting this.

Last edited 3 years ago by hakre (previous) (diff)

hakre3 years ago

Just in case some argu that get_option() might return anything else than an array.

comment:4 nacin20 months ago

  • Keywords reporter-feedback removed
  • Milestone changed from Awaiting Review to 3.5

unset() does appear to be accurate here.

comment:5 nacin19 months ago

  • Owner set to nacin
  • Resolution set to fixed
  • Status changed from new to closed

In [21812]:

Use the key we found using array_search() to unset it from the array. props hakre. fixes #16562.

Note: See TracTickets for help on using tickets.