[wp-trac] [WordPress Trac] #50850: When the deactivate_plugins() function is called in the ABSPATH/wp-admin/includes/plugin.php file, the is_plugin_active_for_network() conditional tag always returns true when the active_sitewide_plugins sitemeta option is set to 1

WordPress Trac noreply at wordpress.org
Wed Aug 5 01:28:10 UTC 2020


#50850: When the deactivate_plugins() function is called in the ABSPATH/wp-
admin/includes/plugin.php file, the is_plugin_active_for_network()
conditional tag always returns true when the active_sitewide_plugins
sitemeta option is set to 1
--------------------------------+-----------------------------
 Reporter:  zenithcity          |      Owner:  (none)
     Type:  defect (bug)        |     Status:  new
 Priority:  normal              |  Milestone:  Awaiting Review
Component:  Options, Meta APIs  |    Version:  5.4.2
 Severity:  critical            |   Keywords:  needs-patch
  Focuses:                      |
--------------------------------+-----------------------------
 On multisite during the process of activating a plugin across the network
 (sitewide plugin activation), I noticed that if the activation process is
 not successful or if errors are triggered, the `active_sitewide_plugins'
 sitemeta option will be set to 1 and this causes the
 **is_plugin_active_for_network()** conditional tag to return true when
 called within the **deactivate_plugins** function, which is so untrue.

 Also, when on the admin or network `plugins.php` screen, the
 **deactivate_plugins()** function triggers the following error becuase the
 **$plugins = get_site_option( 'active_sitewide_plugins' )** code doesn't
 return the correct type (array):

 {{{
  Fatal error: Uncaught Error: Cannot unset string offsets in ABSPATH\wp-
 admin\includes\plugin.php on line 779
 }}}

 Futhermore, after exploring the error, I found that since the
 **active_sitewide_plugins** sitemeta option is set to 1 and the
 **array_keys()** function is used to extract the plugin basenames into a
 new array and merged with non-sitewide activated plugins, then when used
 in the **foreach()** loop, this will always return true.

 {{{#!php
 <?php
 /**
  * @see ABSPATH/wp-admin/includes/plugin.php#L1047
  */
 function validate_active_plugins() {
     $plugins = get_option( 'active_plugins', array() );
     // Validate vartype: array.
     if ( ! is_array( $plugins ) ) {
         update_option( 'active_plugins', array() );
         $plugins = array();
     }

     if ( is_multisite() && current_user_can( 'manage_network_plugins' ) )
 {
         $network_plugins = (array) get_site_option(
 'active_sitewide_plugins', array() );

         // If the 'active_sitewide_plugins' option is set to 1,
         // then the $network_plugins var will contain 0 as the only
 elements
         $plugins         = array_merge( $plugins, array_keys(
 $network_plugins ) );
     }

     if ( empty( $plugins ) ) {
         return array();
     }

     $invalid = array();

     // Invalid plugins get deactivated.
     foreach ( $plugins as $plugin ) {
         $result = validate_plugin( $plugin );
         if ( is_wp_error( $result ) ) {
             $invalid[ $plugin ] = $result;
             deactivate_plugins( $plugin, true );
         }
     }
     return $invalid;
 }
 }}}

 I also ran a test with the **is_plugin_active_for_network()** conditional
 tag using the **in_array()** function to replace the **isset()** function
 in other to see if things would work as normal, and the test was passed:
 {{{#!php
 <?php
 function is_plugin_active_for_network( $plugin ) {
     if ( ! is_multisite() ) {
         return false;
     }

     // Need fix: the $plugins var need to be type-cast into an array
     $plugins = get_site_option( 'active_sitewide_plugins' );

     //if ( isset( $plugins[ $plugin ] ) ) {

     // Note: If the $plugins var is not an array then we have to
     // type-cast it into an array
     if ( in_array( $plugin, (array) $plugins, true ) ) {
         return true;
     }

     return false;
 }
 }}}




 **File:**
 {{{
 ABSPATH/wp-admin/includes/plugin.php
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/50850>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list