Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.374
diff -u -p -r1.374 form.inc
--- includes/form.inc	20 Sep 2009 07:32:17 -0000	1.374
+++ includes/form.inc	21 Sep 2009 04:31:12 -0000
@@ -804,7 +804,12 @@ function _form_validate($elements, &$for
       // checkboxes, can return a valid value of '0'. Instead, check the
       // length if it's a string, and the item count if it's an array.
       if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
-        form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
+        // One more specialized check for file type uploads, which store their
+        // value in the $_FILES array.
+        
+        if ($elements['#type'] !== 'file' || empty($_FILES['files']['name'][$elements['#parents'][0]])) {
+          form_error($elements, t('!name field is required.', array('!name' => $elements['#title'])));
+        }
       }
 
       // Verify that the value is not longer than #maxlength.
Index: modules/simpletest/tests/file.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/file.test,v
retrieving revision 1.44
diff -u -p -r1.44 file.test
--- modules/simpletest/tests/file.test	20 Sep 2009 17:40:41 -0000	1.44
+++ modules/simpletest/tests/file.test	21 Sep 2009 04:31:17 -0000
@@ -623,6 +623,26 @@ class FileSaveUploadTest extends FileHoo
     // Check that file_load_multiple() with no arguments returns FALSE.
     $this->assertFalse(file_load_multiple(), t('No files were loaded.'));
   }
+  
+  /**
+   * Test the file_save_upload() function with required file field.
+   */
+  function testRequired() {
+    // Reset the hook counters to get rid of the 'load' we just called.
+    file_test_reset();
+
+    // Upload a second file.
+    $max_fid_before = db_query('SELECT MAX(fid) AS fid FROM {file}')->fetchField();
+    $image2 = current($this->drupalGetTestFiles('image'));
+    $edit = array('files[file_test_upload]' => drupal_realpath($image2->uri));
+    $this->drupalPost('file-test/upload/1', $edit, t('Submit'));
+    $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+    $this->assertRaw(t('You WIN!'));
+    
+    $this->drupalPost('file-test/upload/1', array(), t('Submit'));
+    $this->assertResponse(200, t('Received a 200 response for posted test file.'));
+    $this->assertRaw(t('field is required'));
+  }
 
   /**
    * Test renaming when uploading over a file that already exists.
Index: modules/simpletest/tests/file_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/file_test.module,v
retrieving revision 1.17
diff -u -p -r1.17 file_test.module
--- modules/simpletest/tests/file_test.module	18 Sep 2009 00:12:48 -0000	1.17
+++ modules/simpletest/tests/file_test.module	21 Sep 2009 04:31:18 -0000
@@ -44,10 +44,11 @@ function file_test_stream_wrappers() {
 /**
  * Form to test file uploads.
  */
-function _file_test_form($form, &$form_state) {
+function _file_test_form($form, &$form_state, $required = FALSE) {
   $form['file_test_upload'] = array(
     '#type' => 'file',
     '#title' => t('Upload an image'),
+    '#required' => $required,
   );
   $form['file_test_replace'] = array(
     '#type' => 'select',
