Index: upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload.module,v
retrieving revision 1.65
diff -u -r1.65 upload.module
--- upload.module	5 Dec 2005 09:11:33 -0000	1.65
+++ upload.module	7 Dec 2005 00:03:39 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: upload.module,v 1.65 2005/12/05 09:11:33 dries Exp $
+// $Id: upload.module,v 1.64 2005/11/30 11:03:58 dries Exp $
 
 /**
  * @file
@@ -145,57 +145,34 @@
 }
 
 function upload_form_alter($form_id, &$form) {
-  if (isset($form['type'])) {
-    if ($form['type']['#value'] .'_node_settings' == $form_id) {
-      $form['workflow']['upload_'. $form['type']['#value']] = array(
-        '#type' => 'radios', '#title' => t('Attachments'), '#default_value' => variable_get('upload_'. $form['type']['#value'], 1),
-        '#options' => array(t('Disabled'), t('Enabled')),
-      );
-    }
-    if ($form['type']['#value'] .'_node_form' == $form_id && variable_get("upload_$node->type", 1) == 1 && user_access('upload files')) {
-      drupal_add_js('misc/progress.js');
-      drupal_add_js('misc/upload.js');
-      $form['attachments'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('File attachments'),
-        '#collapsible' => TRUE,
-        '#collapsed' => empty($node->files),
-        '#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
-        '#prefix' => '<div class="attachments">',
-        '#suffix' => '</div>',
-      );
-      $form['attachments'] += _upload_form($form['#node']);
-      $form['#attributes'] = array('enctype' => 'multipart/form-data');
-    }
+  $node = $form['#node'];
+  if (isset($form['type']) && $form['type']['#value'] .'_node_settings' == $form_id) {
+    $form['workflow']['upload_'. $form['type']['#value']] = array(
+      '#type' => 'radios', '#title' => t('Attachments'), '#default_value' => variable_get('upload_'. $form['type']['#value'], 1),
+      '#options' => array(t('Disabled'), t('Enabled')),
+    );
   }
-}
 
-/**
- * Implementation of hook_nodeapi().
- */
-function upload_nodeapi(&$node, $op, $arg) {
-  switch ($op) {
-    case 'validate':
+  if(isset($form['type']) && $form['type']['#value'] . '_node_form' == $form_id) {
+      // To reset uploads array in session upon entering first time.
+      if(sizeof($_POST) == 0) {
+        $_SESSION['file_uploads'] = NULL;
+      }
       $node->files = upload_load($node);
-      // Double check existing files:
-      if (is_array($node->list)) {
-        foreach ($node->list as $key => $value) {
-          if ($file = file_check_upload($key)) {
-            $node->files[$file->source] = $file;
-            $node->files[$key]->list = $node->list[$key];
-            $node->files[$key]->remove = $node->remove[$key];
-            $node->files[$key]->description = $node->description[$key];
-            if ($file->source) {
-              $filesize += $file->filesize;
-            }
-          }
-        }
+      if($_POST['fileop'] == t('Attach') || $arg == t('Attach') || !$_POST['edit']['op']) {
+        _upload_load_upload($node);
       }
-      else {
-        foreach ($node->files as $key => $file) {
-          $node->list[$key] = $file->list;
-        }
+      if (variable_get("upload_$node->type", 1) == 1 && user_access('upload files')) {
+        $output = upload_form($node);
+        $form['attachments'] = $output;
+        $form['#attributes'] += array('enctype' => 'multipart/form-data');
       }
+  }
+}
+
+
+function _upload_load_upload(&$node) {
+      // Get a new Upload
       if (($file = file_check_upload('upload')) && user_access('upload files')) {
         global $user;
 
@@ -226,6 +203,14 @@
           }
         }
 
+        // Rename possibly executable scripts to prevent accidental execution.
+        // Uploaded files are attachments and should be shown in their original
+        // form, rather than run.
+        if (preg_match('/\.(php|pl|py|cgi|asp)$/i', $file->filename)) {
+          $file->filename .= '.txt';
+          $file->filemime = 'text/plain';
+        }
+
         if ($error['extension'] == count($user->roles) && $user->uid != 1) {
           form_set_error('upload', t('The selected file %name can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', array('%name' => theme('placeholder', $file->filename), '%files-allowed' => theme('placeholder', $extensions))));
         }
@@ -243,12 +228,43 @@
           $node->files[$key] = $file;
         }
       }
-      for ($x = 0; $x < count($_SESSION['file_uploads']); $x++) {
-        $key = 'upload_' . $x;
-        if ($file = file_check_upload($key)) {
-          $node->files[$key] = $file;
+      
+      if( is_array($node->list) || is_array($node->files)) {
+        // Double check existing files:
+        if (is_array($node->list)) {
+          foreach ($node->list as $key => $value) {
+            if ($file = file_check_upload($key)) {
+              $node->files[$file->source] = $file;
+              $node->files[$key]->list = $node->list[$key];
+              $node->files[$key]->remove = $node->remove[$key];
+              $node->files[$key]->description = $node->description[$key];
+
+              if ($file->source) {
+                $filesize += $file->filesize;
+              }
+            }
+          }
+        }
+        else {
+          foreach ($node->files as $key => $file) {
+            $node->list[$key] = $file->list;
+          }
+        }
+  
+        for ($x = 0; $x < count($_SESSION['file_uploads']); $x++) {
+          $key = 'upload_' . $x;
+          if ($file = file_check_upload($key)) {
+            $node->files[$key] = $file;
+          }
         }
       }
+}
+/**
+ * Implementation of hook_nodeapi().
+ */
+function upload_nodeapi(&$node, $op, $arg) {
+  switch ($op) {
+    case 'validate':
       break;
 
     case 'load':
@@ -258,6 +274,9 @@
       break;
 
     case 'view':
+      
+      $node->files = upload_load($node);
+      _upload_load_upload($node);
       if ($node->files && user_access('view uploaded files')) {
         $header = array(t('Attachment'), t('Size'));
         $rows = array();
@@ -357,6 +376,7 @@
 }
 
 function upload_save($node) {
+  _upload_load_upload($node);
   foreach ((array)$node->files as $key => $file) {
     if ($file->source && !$file->remove) {
       // Clean up the session:
@@ -411,6 +431,20 @@
   db_query("DELETE FROM {files} WHERE nid = %d", $node->nid);
 }
 
+function upload_form($node) {
+  drupal_add_js('misc/progress.js');
+  drupal_add_js('misc/upload.js');
+  
+  $form['attachments'] = array(
+    '#type' => 'fieldset', '#title' => t('File attachments'), '#collapsible' => TRUE, '#collapsed' => empty($node->files),
+    '#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
+    '#prefix' => '<div class="attachments">', '#suffix' => '</div>'
+  );
+  $form['attachments'] += _upload_form($node);
+
+  return $form;
+}
+
 function _upload_form($node) {
   $header = array(t('Delete'), t('List'), t('Description'), t('Size'));
   $rows = array();
@@ -420,23 +454,35 @@
   if (is_array($node->files) && count($node->files)) {
     $form['current']['#theme'] = 'upload_form_current';
     $form['current']['description']['#tree'] = TRUE;
+    //$form['current']['vid'] = array('#type' => 'hidden', '#value' => $node->vid);
+    $form['current']['remove']['#tree'] = TRUE;
+    $form['current']['list']['#tree'] = TRUE;
+    $form['current']['remove']['#parents'] = array();
+    $form['current']['list']['#parents'] = array();
+   
     foreach ($node->files as $key => $file) {
       $options[$key] = '';
-      if ($file->remove) {
+      if ($node->remove[$key] || $file->remove) {
         $remove[] = $key;
       }
-      if ($file->list) {
+      if ($node->list[$key] && $file->list) {
         $list[] = $key;
       }
+      
       $description = "<small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>";
-      $form['current']['description'][$key] = array('#type' => 'textfield', '#default_value' => $file->description ? $file->description : $file->filename, '#maxlength' => 256, '#description' => $description );
+      $form['current']['description'][$key] = array('#type' => 'textfield', 
+        '#default_value' => $file->description ? $file->description : $file->filename, '#maxlength' => 256, '#description' => $description );
       $form['current']['size'][$key] = array('#type' => 'markup', '#value' => format_size($file->filesize));
     }
-    $form['current']['remove'] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $remove);
-    $form['current']['list'] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $list);
+
+    $form['current']['remove'] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $remove, '#tree' => TRUE);
+    $form['current']['list'] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $list, '#tree' => TRUE);
+
     $form['files'][$key] = array('#type' => 'hidden', '#value' => 1);
   }
 
+
+
   if (user_access('upload files')) {
 
     $form['new']['upload'] = array('#type' => 'file', '#title' => t('Attach new file'), '#size' => 40);
@@ -445,6 +491,8 @@
     $form['fileop'] = array('#type' => 'hidden', '#value' => url('upload/js', NULL, NULL, TRUE), '#attributes' => array('class' => 'upload'));
   }
 
+
+
   return $form;
 }
 
@@ -474,7 +522,7 @@
 
 function upload_load($node) {
   $files = array();
-
+  
   if ($node->vid) {
     $result = db_query("SELECT * FROM {files} WHERE vid = %d", $node->vid);
     while ($file = db_fetch_object($result)) {
@@ -512,12 +560,17 @@
 function upload_js() {
   // We only do the upload.module part of the node validation process.
   $node = array2object($_POST['edit']);
-  upload_nodeapi($node, 'validate', NULL);
+  
+  $node->files = upload_load($node);
+  _upload_load_upload($node);
+
   $form = _upload_form($node);
   $form = _form_builder('upload_js', $form);
+  
   $output = theme('status_messages') . form_render($form);
 
   // We send the updated file attachments form.
   print drupal_call_js('window.parent.iframeHandler', $output);
   exit;
 }
+
