Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.121.2.10
diff -u -p -r1.121.2.10 file.inc
--- includes/file.inc	1 Feb 2010 16:14:58 -0000	1.121.2.10
+++ includes/file.inc	26 Feb 2010 07:38:40 -0000
@@ -451,6 +451,43 @@ function file_space_used($uid = NULL) {
 }
 
 /**
+ * Gets value from $_FILES array, supports trees
+ * 
+ * @param $source
+ *   A string specifying the name of upload field to get value for. 
+ *   For INTERNAL use it can be an array of keys left to walk through.
+ * @param $what
+ *   A string specifying which value to get for $source ('name', 'tmp_name', etc.)
+ * @param $current
+ *   INTERNAL USE ONLY! Current position in $_FILES structure.
+ * @return
+ *   Value of $what for $source or NULL if there is no such value
+ */
+function _file_tree_get_value($source, $what, $current = NULL)
+{
+  if (!is_array($source))
+  {
+    //First iteration, preparing for possible recursion
+    $source = explode('][', $source);
+    if (!isset($_FILES['files'][$what]) || !is_array($_FILES['files'][$what]))
+      return NULL;
+    $current = $_FILES['files'][$what];
+  }
+  
+  $level_name = array_shift($source);
+  
+  //If there is no searched value or nowhere to go on next iteration of recursion,
+  // then return nothing
+  if (!isset($current[$level_name]) || (count($source) && !is_array($current[$level_name])))
+    return NULL;
+  
+  if (!count($source))
+    return $current[$level_name];
+  else
+    return _file_tree_get_value($source, NULL, $current[$level_name]);
+}
+
+/**
  * Saves a file upload to a new location. The source file is validated as a
  * proper upload and handled as such.
  *
@@ -491,10 +528,12 @@ function file_save_upload($source, $vali
   }
 
   // If a file was uploaded, process it.
-  if (isset($_FILES['files']) && $_FILES['files']['name'][$source] && is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
+  $name = _file_tree_get_value($source, 'name');
+  $tmp_name = _file_tree_get_value($source, 'tmp_name');
+  if (isset($_FILES['files']) && $name && is_uploaded_file($tmp_name)) {
     // Check for file upload errors and return FALSE if a
     // lower level system error occurred.
-    switch ($_FILES['files']['error'][$source]) {
+    switch (_file_tree_get_value($source, 'error')) {
       // @see http://php.net/manual/en/features.file-upload.errors.php
       case UPLOAD_ERR_OK:
         break;
@@ -525,8 +564,8 @@ function file_save_upload($source, $vali
 
     // Begin building file object.
     $file = new stdClass();
-    $file->filename = file_munge_filename(trim(basename($_FILES['files']['name'][$source]), '.'), $extensions);
-    $file->filepath = $_FILES['files']['tmp_name'][$source];
+    $file->filename = file_munge_filename(trim(basename($name), '.'), $extensions);
+    $file->filepath = $tmp_name;
     $file->filemime = file_get_mimetype($file->filename);
 
     // If the destination is not provided, or is not writable, then use the
@@ -537,7 +576,7 @@ function file_save_upload($source, $vali
 
     $file->source = $source;
     $file->destination = file_destination(file_create_path($dest .'/'. $file->filename), $replace);
-    $file->filesize = $_FILES['files']['size'][$source];
+    $file->filesize = _file_tree_get_value($source, 'size');
 
     // Call the validation functions.
     $errors = array();
@@ -576,7 +615,7 @@ function file_save_upload($source, $vali
     // Move uploaded files from PHP's upload_tmp_dir to Drupal's temporary directory.
     // This overcomes open_basedir restrictions for future file operations.
     $file->filepath = $file->destination;
-    if (!move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->filepath)) {
+    if (!move_uploaded_file($tmp_name, $file->filepath)) {
       form_set_error($source, t('File upload error. Could not move uploaded file.'));
       watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->filepath));
       return 0;
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.265.2.31
diff -u -p -r1.265.2.31 form.inc
--- includes/form.inc	7 Dec 2009 15:54:52 -0000	1.265.2.31
+++ includes/form.inc	26 Feb 2010 07:38:41 -0000
@@ -968,11 +968,10 @@ function _form_builder_handle_input_elem
     $form['#name'] = $name;
     if ($form['#type'] == 'file') {
       // To make it easier to handle $_FILES in file.inc, we place all
-      // file fields in the 'files' array. Also, we do not support
-      // nested file names.
+      // file fields in the 'files' array. Finally, we support nested filenames.
       $form['#name'] = 'files['. $form['#name'] .']';
     }
-    elseif (count($form['#parents'])) {
+    if (count($form['#parents'])) {
       $form['#name'] .= '['. implode('][', $form['#parents']) .']';
     }
     array_unshift($form['#parents'], $name);
