diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index 931329951f..b2e7f2d6f8 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -566,27 +566,27 @@ function remove_accents($string) { } /** - * Filters certain characters from the file name. + * Sanitizes a filename replacing whitespace with dashes * - * Turns all strings to lowercase removing most characters except alphanumeric - * with spaces, dashes and periods. All spaces and underscores are converted to - * dashes. Multiple dashes are converted to a single dash. Finally, if the file - * name ends with a dash, it is removed. + * Removes special characters that are illegal in filenames on certain + * operating systems and special characters requiring special escaping + * to manipulate at the command line. Replaces spaces and consecutive + * dashes with a single dash. Trim period, dash and underscore from beginning + * and end of filename. * * @since 2.1.0 * - * @param string $name The file name - * @return string Sanitized file name + * @param string $filename The filename to be sanitized + * @return string The sanitized filename */ -function sanitize_file_name( $name ) { // Like sanitize_title, but with periods - $name = strtolower( $name ); - $name = preg_replace('/&.+?;/', '', $name); // kill entities - $name = str_replace( '_', '-', $name ); - $name = preg_replace('/[^a-z0-9\s-.]/', '', $name); - $name = preg_replace('/\s+/', '-', $name); - $name = preg_replace('|-+|', '-', $name); - $name = trim($name, '-'); - return $name; +function sanitize_file_name( $filename ) { + $filename_raw = $filename; + $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}"); + $special_chars = apply_filters('sanitize_file_name_chars', $special_chars, $filename_raw); + $filename = str_replace($special_chars, '', $filename); + $filename = preg_replace('/[\s-]+/', '-', $filename); + $filename = trim($filename, '.-_'); + return apply_filters('sanitize_file_name', $filename, $filename_raw); } /** diff --git a/wp-includes/functions.php b/wp-includes/functions.php index e2b6ff93f8..3fee35fa9a 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -2013,12 +2013,14 @@ function wp_upload_dir( $time = null ) { * @return string New filename, if given wasn't unique. */ function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) { - $filename = strtolower( $filename ); + // sanitize the file name before we begin processing + $filename = sanitize_file_name($filename); + // separate the filename into a name and extension $info = pathinfo($filename); $ext = !empty($info['extension']) ? $info['extension'] : ''; $name = basename($filename, ".{$ext}"); - + // edge case: if file is named '.ext', treat as an empty name if( $name === ".$ext" ) $name = ''; @@ -2030,11 +2032,7 @@ function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) $number = ''; if ( !empty( $ext ) ) - $ext = strtolower( ".$ext" ); - - $filename = str_replace( $ext, '', $filename ); - // Strip % so the server doesn't try to decode entities. - $filename = str_replace('%', '', sanitize_title_with_dashes( $filename ) ) . $ext; + $ext = ".$ext"; while ( file_exists( $dir . "/$filename" ) ) { if ( '' == "$number$ext" )