diff --git a/src/wp-admin/includes/class-wp-upgrader.php b/src/wp-admin/includes/class-wp-upgrader.php index 1fbfa99e4c..c54384e742 100644 --- a/src/wp-admin/includes/class-wp-upgrader.php +++ b/src/wp-admin/includes/class-wp-upgrader.php @@ -196,6 +196,7 @@ class WP_Upgrader { /* translators: %s: Directory name. */ $this->strings['fs_no_folder'] = __( 'Unable to locate needed folder (%s).' ); + $this->strings['no_package'] = __( 'Package not available.' ); $this->strings['download_failed'] = __( 'Download failed.' ); $this->strings['installing_package'] = __( 'Installing the latest version…' ); $this->strings['no_files'] = __( 'The package contains no files.' ); @@ -527,7 +528,10 @@ class WP_Upgrader { set_time_limit( 300 ); } - if ( empty( $source ) || empty( $destination ) ) { + if ( + ( ! is_string( $source ) || '' === $source || trim( $source ) !== $source ) || + ( ! is_string( $destination ) || '' === $destination || trim( $destination ) !== $destination ) + ) { return new WP_Error( 'bad_request', $this->strings['bad_request'] ); } $this->skin->feedback( 'installing_package' ); diff --git a/tests/phpunit/tests/admin/wpUpgrader.php b/tests/phpunit/tests/admin/wpUpgrader.php index 9de3ed07cd..3d38631bfa 100644 --- a/tests/phpunit/tests/admin/wpUpgrader.php +++ b/tests/phpunit/tests/admin/wpUpgrader.php @@ -137,6 +137,7 @@ class Tests_Admin_WpUpgrader extends WP_UnitTestCase { 'fs_no_plugins_dir', 'fs_no_themes_dir', 'fs_no_folder', + 'no_package', 'download_failed', 'installing_package', 'no_files', @@ -777,16 +778,36 @@ class Tests_Admin_WpUpgrader extends WP_UnitTestCase { */ public function data_install_package_invalid_paths() { return array( - 'empty string' => array( 'path' => '' ), + 'empty string' => array( 'path' => '' ), // Type checks. - 'empty array' => array( 'path' => array() ), - '(int) 0' => array( 'path' => 0 ), - '(int) -0' => array( 'path' => -0 ), - '(float) 0.0' => array( 'path' => 0.0 ), - '(float) -0.0' => array( 'path' => -0.0 ), - '(bool) false' => array( 'path' => false ), - 'null' => array( 'path' => null ), + 'empty array' => array( 'path' => array() ), + 'populated array' => array( 'path' => array( '/' ) ), + '(int) 0' => array( 'path' => 0 ), + '(int) -0' => array( 'path' => -0 ), + '(int) -1' => array( 'path' => -1 ), + '(int) 1' => array( 'path' => 1 ), + '(float) 0.0' => array( 'path' => 0.0 ), + '(float) -0.0' => array( 'path' => -0.0 ), + '(float) 1.0' => array( 'path' => 1.0 ), + '(float) -1.0' => array( 'path' => -1.0 ), + '(bool) false' => array( 'path' => false ), + '(bool) true' => array( 'path' => true ), + 'null' => array( 'path' => null ), + 'empty object' => array( 'path' => new stdClass() ), + 'populated object' => array( 'path' => (object) array( '/' ) ), + + // Ensures that `trim()` is run triggering an empty array. + 'a string with spaces' => array( 'path' => ' ' ), + 'a string with tabs' => array( 'path' => "\t\t" ), + 'a string with new lines' => array( 'path' => "\n\n" ), + 'a string with carriage returns' => array( 'path' => "\r\r" ), + + // Ensure that strings with leading/trailing whitespace are invalid. + 'a path with a leading space' => array( 'path' => ' /path' ), + 'a path with a trailing space' => array( 'path' => '/path ' ), + 'a path with a leading tab' => array( 'path' => "\t/path" ), + 'a path with a trailing tab' => array( 'path' => "/path\t" ), ); } @@ -1556,6 +1577,31 @@ class Tests_Admin_WpUpgrader extends WP_UnitTestCase { $this->assertSame( __FILE__, $result ); } + /** + * Tests that `WP_Upgrader::download_package()` returns a WP_Error object + * for an empty package. + * + * @ticket 59712 + * + * @covers WP_Upgrader::download_package + */ + public function test_download_package_should_return_a_wp_error_object_for_an_empty_package() { + self::$instance->init(); + + $result = self::$instance->download_package( '' ); + + $this->assertWPError( + $result, + 'WP_Upgrader::download_package() did not return a WP_Error object' + ); + + $this->assertSame( + 'no_package', + $result->get_error_code(), + 'Unexpected WP_Error code' + ); + } + /** * Tests that `WP_Upgrader::download_package()` returns a file with the * package name in it.