@@ -997,16 +997,22 @@ function file_build_uri($path) {
997997 * @return
998998 * The destination filepath, or FALSE if the file already exists
999999 * and FILE_EXISTS_ERROR is specified.
1000+ *
1001+ * @throws RuntimeException
1002+ * Thrown if the filename contains invalid UTF-8.
10001003 */
10011004function file_destination ($ destination , $ replace ) {
1005+ $ basename = drupal_basename ($ destination );
1006+ if (!drupal_validate_utf8 ($ basename )) {
1007+ throw new RuntimeException (sprintf ("Invalid filename '%s' " , $ basename ));
1008+ }
10021009 if (file_exists ($ destination )) {
10031010 switch ($ replace ) {
10041011 case FILE_EXISTS_REPLACE :
10051012 // Do nothing here, we want to overwrite the existing file.
10061013 break ;
10071014
10081015 case FILE_EXISTS_RENAME :
1009- $ basename = drupal_basename ($ destination );
10101016 $ directory = drupal_dirname ($ destination );
10111017 $ destination = file_create_filename ($ basename , $ directory );
10121018 break ;
@@ -1222,11 +1228,20 @@ function file_unmunge_filename($filename) {
12221228 * @return
12231229 * File path consisting of $directory and a unique filename based off
12241230 * of $basename.
1231+ *
1232+ * @throws RuntimeException
1233+ * Thrown if the $basename is not valid UTF-8 or another error occurs
1234+ * stripping control characters.
12251235 */
12261236function file_create_filename ($ basename , $ directory ) {
1237+ $ original = $ basename ;
12271238 // Strip control characters (ASCII value < 32). Though these are allowed in
12281239 // some filesystems, not many applications handle them well.
12291240 $ basename = preg_replace ('/[\x00-\x1F]/u ' , '_ ' , $ basename );
1241+ if (preg_last_error () !== PREG_NO_ERROR ) {
1242+ throw new RuntimeException (sprintf ("Invalid filename '%s' " , $ original ));
1243+ }
1244+
12301245 if (substr (PHP_OS , 0 , 3 ) == 'WIN ' ) {
12311246 // These characters are not allowed in Windows filenames
12321247 $ basename = str_replace (array (': ' , '* ' , '? ' , '" ' , '< ' , '> ' , '| ' ), '_ ' , $ basename );
@@ -1567,7 +1582,13 @@ function file_save_upload($form_field_name, $validators = array(), $destination
15671582 if (substr ($ destination , -1 ) != '/ ' ) {
15681583 $ destination .= '/ ' ;
15691584 }
1570- $ file ->destination = file_destination ($ destination . $ file ->filename , $ replace );
1585+ try {
1586+ $ file ->destination = file_destination ($ destination . $ file ->filename , $ replace );
1587+ }
1588+ catch (RuntimeException $ e ) {
1589+ drupal_set_message (t ('The file %source could not be uploaded because the name is invalid. ' , array ('%source ' => $ form_field_name )), 'error ' );
1590+ return FALSE ;
1591+ }
15711592 // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
15721593 // there's an existing file so we need to bail.
15731594 if ($ file ->destination === FALSE ) {
@@ -2134,9 +2155,33 @@ function file_download_access($uri) {
21342155 * 'filename', and 'name' members corresponding to the matching files.
21352156 */
21362157function file_scan_directory ($ dir , $ mask , $ options = array (), $ depth = 0 ) {
2158+ // Default nomask option.
2159+ $ nomask = '/(\.\.?|CVS)$/ ' ;
2160+
2161+ // Overrides the $nomask variable accordingly if $options['nomask'] is set.
2162+ //
2163+ // Allow directories specified in settings.php to be ignored. You can use this
2164+ // to not check for files in common special-purpose directories. For example,
2165+ // node_modules and bower_components. Ignoring irrelevant directories is a
2166+ // performance boost.
2167+ if (!isset ($ options ['nomask ' ])) {
2168+ $ ignore_directories = variable_get (
2169+ 'file_scan_ignore_directories ' ,
2170+ array ()
2171+ );
2172+
2173+ foreach ($ ignore_directories as $ index => $ ignore_directory ) {
2174+ $ ignore_directories [$ index ] = preg_quote ($ ignore_directory , '/ ' );
2175+ }
2176+
2177+ if (!empty ($ ignore_directories )) {
2178+ $ nomask = '/^(\.\.?)|CVS| ' . implode ('| ' , $ ignore_directories ) . '$/ ' ;
2179+ }
2180+ }
2181+
21372182 // Merge in defaults.
21382183 $ options += array (
2139- 'nomask ' => ' /(\.\.?|CVS)$/ ' ,
2184+ 'nomask ' => $ nomask ,
21402185 'callback ' => 0 ,
21412186 'recurse ' => TRUE ,
21422187 'key ' => 'uri ' ,
0 commit comments