Make WordPress Core

Changeset 59257


Ignore:
Timestamp:
10/18/2024 11:35:02 PM (7 weeks ago)
Author:
azaozz
Message:

Upgrade/Install: Return WP_Error when source files cannot be found.

Fixes a fatal error in array_keys() (PHP 8.0+) as $wp_filesystem->dirlist() will return false when the source directory doesn't exist or becomes unreadable for some reason.

Props: verygoode, lifelightweb, da5f656f, costdev, afragen, azaozz
Fixes #61114

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-upgrader.php

    r59039 r59257  
    205205        $this->strings['incompatible_archive'] = __( 'The package could not be installed.' );
    206206        $this->strings['files_not_writable']   = __( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' );
     207        $this->strings['dir_not_readable']     = __( 'A directory could not be read.' );
    207208
    208209        $this->strings['maintenance_start'] = __( 'Enabling Maintenance mode…' );
     
    559560        $local_destination = $destination;
    560561
    561         $source_files       = array_keys( $wp_filesystem->dirlist( $remote_source ) );
     562        $dirlist = $wp_filesystem->dirlist( $remote_source );
     563
     564        if ( false === $dirlist ) {
     565            return new WP_Error( 'source_read_failed', $this->strings['fs_error'], $this->strings['dir_not_readable'] );
     566        }
     567
     568        $source_files       = array_keys( $dirlist );
    562569        $remote_destination = $wp_filesystem->find_folder( $local_destination );
    563570
     
    606613        // Has the source location changed? If so, we need a new source_files list.
    607614        if ( $source !== $remote_source ) {
    608             $source_files = array_keys( $wp_filesystem->dirlist( $source ) );
     615            $dirlist = $wp_filesystem->dirlist( $source );
     616
     617            if ( false === $dirlist ) {
     618                return new WP_Error( 'new_source_read_failed', $this->strings['fs_error'], $this->strings['dir_not_readable'] );
     619            }
     620
     621            $source_files = array_keys( $dirlist );
    609622        }
    610623
  • trunk/tests/phpunit/tests/admin/wpUpgrader.php

    r58022 r59257  
    950950
    951951    /**
     952     * Tests that `WP_Upgrader::install_package()` returns a WP_Error object
     953     * when the source directory's file list cannot be retrieved.
     954     *
     955     * @ticket 61114
     956     *
     957     * @covers WP_Upgrader::install_package
     958     */
     959    public function test_install_package_should_return_wp_error_when_source_directory_file_list_cannot_be_retrieved() {
     960        self::$instance->generic_strings();
     961
     962        self::$upgrader_skin_mock
     963                ->expects( $this->once() )
     964                ->method( 'feedback' )
     965                ->with( 'installing_package' );
     966
     967        self::$wp_filesystem_mock
     968                ->expects( $this->once() )
     969                ->method( 'dirlist' )
     970                ->willReturn( false );
     971
     972        $args = array(
     973            'source'      => '/',
     974            'destination' => '/',
     975        );
     976
     977        $actual = self::$instance->install_package( $args );
     978
     979        $this->assertWPError(
     980            $actual,
     981            'WP_Upgrader::install_package() did not return a WP_Error object'
     982        );
     983
     984        $this->assertSame(
     985            'source_read_failed',
     986            $actual->get_error_code(),
     987            'Unexpected WP_Error code'
     988        );
     989    }
     990
     991    /**
     992     * Tests that `WP_Upgrader::install_package()` returns a WP_Error object
     993     * when the source directory is filtered and its file list cannot be retrieved.
     994     *
     995     * @ticket 61114
     996     *
     997     * @covers WP_Upgrader::install_package
     998     *
     999     * @runInSeparateProcess
     1000     * @preserveGlobalState disabled
     1001     */
     1002    public function test_install_package_should_return_wp_error_when_a_filtered_source_directory_file_list_cannot_be_retrieved() {
     1003        define( 'FS_CHMOD_DIR', 0755 );
     1004
     1005        self::$instance->generic_strings();
     1006
     1007        self::$upgrader_skin_mock
     1008                ->expects( $this->once() )
     1009                ->method( 'feedback' )
     1010                ->with( 'installing_package' );
     1011
     1012        $first_source = array(
     1013            'subdir' => array(
     1014                'name'  => 'subdir',
     1015                'type'  => 'd',
     1016                'files' => array( 'subfile.php' ),
     1017            ),
     1018        );
     1019
     1020        self::$wp_filesystem_mock
     1021                ->expects( $this->exactly( 2 ) )
     1022                ->method( 'dirlist' )
     1023                ->willReturn( $first_source, false );
     1024
     1025        $args = array(
     1026            'source'      => '/',
     1027            'destination' => '/',
     1028        );
     1029
     1030        // Filter the source to something else.
     1031        add_filter(
     1032            'upgrader_source_selection',
     1033            static function () {
     1034                return '/not_original_source/';
     1035            }
     1036        );
     1037
     1038        $actual = self::$instance->install_package( $args );
     1039
     1040        $this->assertWPError(
     1041            $actual,
     1042            'WP_Upgrader::install_package() did not return a WP_Error object'
     1043        );
     1044
     1045        $this->assertSame(
     1046            'new_source_read_failed',
     1047            $actual->get_error_code(),
     1048            'Unexpected WP_Error code'
     1049        );
     1050    }
     1051
     1052    /**
    9521053     * Tests that `WP_Upgrader::install_package()` adds a trailing slash to
    9531054     * the source directory of a single file.
Note: See TracChangeset for help on using the changeset viewer.