Make WordPress Core

Changeset 57736


Ignore:
Timestamp:
02/28/2024 06:02:09 PM (3 months ago)
Author:
costdev
Message:

Plugin Dependencies: Don't assume API response has a slug property.

Previously, WP_Plugin_Dependencies::get_dependency_api_data() attempted to set an array key using the slug property returned in a Plugins API response. However, the Plugins API response is filterable and may not contain a slug property.

Earlier in the method, a local $slug variable is used as a key for the same array.

For safety and consistency, this replaces array key references to $information->slug with $slug.

Follow-up to [57545].

Props pbiron, afragen, swissspidy, costdev.
Fixes #60540.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-plugin-dependencies.php

    r57658 r57736  
    695695            self::$dependency_api_data[ $slug ] = (array) $information;
    696696            // plugins_api() returns 'name' not 'Name'.
    697             self::$dependency_api_data[ $information->slug ]['Name'] = self::$dependency_api_data[ $information->slug ]['name'];
     697            self::$dependency_api_data[ $slug ]['Name'] = self::$dependency_api_data[ $slug ]['name'];
    698698            set_site_transient( 'wp_plugin_dependencies_plugin_data', self::$dependency_api_data, 0 );
    699699        }
  • trunk/tests/phpunit/tests/admin/plugin-dependencies/getDependencyData.php

    r57545 r57736  
    7171        $this->assertFalse( $actual );
    7272    }
     73
     74    /**
     75     * Tests that a 'slug' key in the Plugins API response object is not assumed.
     76     *
     77     * @ticket 60540
     78     */
     79    public function test_should_not_assume_a_slug_key_exists_in_the_response() {
     80        global $pagenow;
     81
     82        // Backup $pagenow.
     83        $old_pagenow = $pagenow;
     84
     85        // Ensure is_admin() and screen checks pass.
     86        $pagenow = 'plugins.php';
     87        set_current_screen( 'plugins.php' );
     88
     89        add_filter(
     90            'plugins_api',
     91            static function ( $bypass, $action, $args ) {
     92                if ( 'plugin_information' === $action && isset( $args->slug ) && 'dependency' === $args->slug ) {
     93                    $bypass = (object) array( 'name' => 'Dependency 1' );
     94                }
     95                return $bypass;
     96            },
     97            10,
     98            3
     99        );
     100
     101        $this->set_property_value(
     102            'plugins',
     103            array(
     104                'dependent/dependent.php' => array(
     105                    'Name'            => 'Dependent',
     106                    'RequiresPlugins' => 'dependency',
     107                ),
     108            )
     109        );
     110
     111        self::$instance->initialize();
     112
     113        $actual = $this->get_property_value( 'dependency_api_data' );
     114
     115        // Restore $pagenow.
     116        $pagenow = $old_pagenow;
     117
     118        $this->assertSame(
     119            array(
     120                'dependency' => array(
     121                    'name'     => 'Dependency 1',
     122                    'external' => true,
     123                    'Name'     => 'Dependency 1',
     124                ),
     125            ),
     126            $actual
     127        );
     128    }
    73129}
Note: See TracChangeset for help on using the changeset viewer.