diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 46d9a9068a..153b9dba44 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -1725,7 +1725,8 @@ function remove_accents( $string ) { * operating systems and special characters requiring special escaping * to manipulate at the command line. Replaces spaces and consecutive * dashes with a single dash. Trims period, dash and underscore from beginning - * and end of filename. + * and end of filename. It is not guaranteed that this function will return a + * filename that is allowed to be uploaded. * * @since 2.1.0 * @@ -1750,6 +1751,14 @@ function sanitize_file_name( $filename ) { $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); $filename = trim( $filename, '.-_' ); + if ( false === strpos( $filename, '.' ) ) { + $mime_types = wp_get_mime_types(); + $filetype = wp_check_filetype( 'test.' . $filename, $mime_types ); + if ( $filetype['ext'] === $filename ) { + $filename = 'unnamed-file.' . $filetype['ext']; + } + } + // Split the filename into a base and extension[s] $parts = explode('.', $filename); diff --git a/tests/phpunit/tests/formatting/SanitizeFileName.php b/tests/phpunit/tests/formatting/SanitizeFileName.php index 8927fec774..d26b87134e 100644 --- a/tests/phpunit/tests/formatting/SanitizeFileName.php +++ b/tests/phpunit/tests/formatting/SanitizeFileName.php @@ -56,4 +56,15 @@ class Tests_Formatting_SanitizeFileName extends WP_UnitTestCase { function test_replaces_percent_sign() { $this->assertEquals( 'a22b.jpg', sanitize_file_name( 'a%22b.jpg' ) ); } + + function test_replaces_unnammed_file_extensions() { + // Test filenames with both supported and unsupported extensions. + $this->assertEquals( 'unnamed-file.exe', sanitize_file_name( '_.exe' ) ); + $this->assertEquals( 'unnamed-file.jpg', sanitize_file_name( '_.jpg' ) ); + } + + function test_replaces_unnammed_file_extensionless() { + // Test a filenames that becomes extensionless. + $this->assertEquals( 'no-extension', sanitize_file_name( '_.no-extension' ) ); + } }