From 735b3543dbdf852094beb15323d4c3037e6c5fdb Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Mon, 16 Dec 2019 23:22:00 +0000 Subject: [PATCH] Upload: - Fix PHP warnings in `wp_unique_filename()` when the destination directory is unreadable. - Run the final name collision test only for files that are saved to the uploads directory. - Update the unit tests to match. Props eden159, audrasjb, azaozz. Fixes #48960 for trunk. git-svn-id: https://develop.svn.wordpress.org/trunk@46965 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 12 +++++++++--- tests/phpunit/tests/functions.php | 12 ++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 500aa35a0e..4cc62be66d 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2472,11 +2472,17 @@ function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) // Prevent collisions with existing file names that contain dimension-like strings // (whether they are subsizes or originals uploaded prior to #42437). + $upload_dir = wp_get_upload_dir(); // The (resized) image files would have name and extension, and will be in the uploads dir. - if ( @is_dir( $dir ) && $name && $ext ) { - // List of all files and directories contained in $dir (with the "dot" files removed). - $files = array_diff( scandir( $dir ), array( '.', '..' ) ); + if ( $name && $ext && @is_dir( $dir ) && false !== strpos( $dir, $upload_dir['basedir'] ) ) { + // List of all files and directories contained in $dir. + $files = @scandir( $dir ); + + if ( ! empty( $files ) ) { + // Remove "dot" dirs. + $files = array_diff( $files, array( '.', '..' ) ); + } if ( ! empty( $files ) ) { while ( _wp_check_existing_file_names( $filename, $files ) ) { diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 4b9935b1d6..41d814b9d6 100644 --- a/tests/phpunit/tests/functions.php +++ b/tests/phpunit/tests/functions.php @@ -201,11 +201,21 @@ class Tests_Functions extends WP_UnitTestCase { function test_unique_filename_with_dimension_like_filename() { $testdir = DIR_TESTDATA . '/images/'; + add_filter( 'upload_dir', array( $this, 'upload_dir_patch_basedir' ) ); + // Test collision with "dimension-like" original filename. $this->assertEquals( 'one-blue-pixel-100x100-1.png', wp_unique_filename( $testdir, 'one-blue-pixel-100x100.png' ) ); // Test collision with existing sub-size filename. // Existing files: one-blue-pixel-100x100.png, one-blue-pixel-1-100x100.png. $this->assertEquals( 'one-blue-pixel-2.png', wp_unique_filename( $testdir, 'one-blue-pixel.png' ) ); + + remove_filter( 'upload_dir', array( $this, 'upload_dir_patch_basedir' ) ); + } + + // Callback to patch "basedir" when used in `wp_unique_filename()`. + function upload_dir_patch_basedir( $upload_dir ) { + $upload_dir['basedir'] = DIR_TESTDATA . '/images/'; + return $upload_dir; } function test_is_serialized() { @@ -228,6 +238,7 @@ class Tests_Functions extends WP_UnitTestCase { ) ), ); + foreach ( $cases as $case ) { $this->assertTrue( is_serialized( $case ), "Serialized data: $case" ); } @@ -237,6 +248,7 @@ class Tests_Functions extends WP_UnitTestCase { 'garbage:a:0:garbage;', 's:4:test;', ); + foreach ( $not_serialized as $case ) { $this->assertFalse( is_serialized( $case ), "Test data: $case" ); }