Account for case when no reply-to is set in user prefs
[squirrelmail.git] / src / compose.php
index bd5599f2f8d0c8ad5a00b9279109872b47f1a7d8..fb0a9c57f5af6233667736e6e71d4165b933c0b4 100644 (file)
@@ -10,7 +10,7 @@
  *    - Send mail
  *    - Save As Draft
  *
- * @copyright © 1999-2009 The SquirrelMail Project Team
+ * @copyright 1999-2012 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -138,6 +138,8 @@ if ( !sqgetGlobalVar('smaction',$action) )
     if ( sqgetGlobalVar('smaction_edit_new',$tmp) )   $action = 'edit_as_new';
 }
 
+sqgetGlobalVar('smtoken', $submitted_token, $SQ_GLOBAL, '');
+
 /**
  * Here we decode the data passed in from mailto.php.
  */
@@ -194,12 +196,10 @@ function replyAllString($header) {
     $url_replytoallcc = '';
     foreach( $url_replytoall_ar as $email => $personal) {
         if ($personal) {
-            // if personal name contains address separator then surround
-            // the personal name with double quotes.
-            if (strpos($personal,',') !== false) {
-                $personal = '"'.$personal.'"';
-            }
-            $url_replytoallcc .= ", $personal <$email>";
+            // always quote personal name (can't just quote it if
+            // it contains a comma separator, since it might still
+            // be encoded)
+            $url_replytoallcc .= ", \"$personal\" <$email>";
         } else {
             $url_replytoallcc .= ', '. $email;
         }
@@ -412,6 +412,11 @@ if (empty($mailbox)) {
 }
 
 if ($draft) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     /*
      * Set $default_charset to correspond with the user's selection
      * of language interface.
@@ -466,11 +471,17 @@ if ($draft) {
 }
 
 if ($send) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     if (isset($_FILES['attachfile']) &&
             $_FILES['attachfile']['tmp_name'] &&
             $_FILES['attachfile']['tmp_name'] != 'none') {
         $AttachFailure = saveAttachedFiles($session);
     }
+    
     if (checkInput(false) && !isset($AttachFailure)) {
         if ($mailbox == "All Folders") {
             /* We entered compose via the search results page */
@@ -587,6 +598,11 @@ if ($send) {
         /* sqimap_logout($imapConnection); */
     }
 } elseif (isset($html_addr_search_done)) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     if ($compose_new_win == '1') {
         compose_Header($color, $mailbox);
     }
@@ -631,6 +647,11 @@ if ($send) {
      */
     include_once('./addrbook_search_html.php');
 } elseif (isset($attach)) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     if ($compose_new_win == '1') {
         compose_Header($color, $mailbox);
     } else {
@@ -642,6 +663,11 @@ if ($send) {
     showInputForm($session);
 }
 elseif (isset($sigappend)) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     $signature = $idents[$identity]['signature'];
 
     $body .= "\n\n".($prefix_sig==true? "-- \n":'').$signature;
@@ -652,6 +678,11 @@ elseif (isset($sigappend)) {
     }
     showInputForm($session);
 } elseif (isset($do_delete)) {
+
+    // validate security token
+    //
+    sm_validate_security_token($submitted_token, 3600, TRUE);
+
     if ($compose_new_win == '1') {
         compose_Header($color, $mailbox);
     } else {
@@ -703,6 +734,11 @@ elseif (isset($sigappend)) {
 
     $values = newMail($mailbox,$passed_id,$passed_ent_id, $action, $session);
 
+    // forward as attachment - subject is in the message in session
+    //
+    if ($action == 'forward_as_attachment' && empty($values['subject']))
+        $subject = $composeMessage->rfc822_header->subject;
+
     /* in case the origin is not read_body.php */
     if (isset($send_to)) {
         $values['send_to'] = $send_to;
@@ -914,6 +950,12 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
             case ('forward_as_attachment'):
                 $subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
                 $composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
+                $subject = decodeHeader($orig_header->subject,false,false,true);
+                $subject = str_replace('"', "'", $subject);
+                $subject = trim($subject);
+                if (substr(strtolower($subject), 0, 4) != 'fwd:') {
+                    $subject = 'Fwd: ' . $subject;
+                }
                 $body = '';
                 break;
             case ('reply_all'):
@@ -922,20 +964,22 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
                 } else {
                     $send_to_cc = replyAllString($orig_header);
                     $send_to_cc = decodeHeader($send_to_cc,false,false,true);
+                    $send_to_cc = str_replace('""', '"', $send_to_cc);
                 }
             case ('reply'):
                 // skip this if send_to was already set right above here
                 if(!$send_to) {
                     $send_to = $orig_header->reply_to;
                     if (is_array($send_to) && count($send_to)) {
-                        $send_to = $orig_header->getAddr_s('reply_to');
+                        $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
                     } else if (is_object($send_to)) { /* unneccesarry, just for failsafe purpose */
-                        $send_to = $orig_header->getAddr_s('reply_to');
+                        $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
                     } else {
-                        $send_to = $orig_header->getAddr_s('from');
+                        $send_to = $orig_header->getAddr_s('from', ',', FALSE, TRUE);
                     }
                 }
                 $send_to = decodeHeader($send_to,false,false,true);
+                $send_to = str_replace('""', '"', $send_to);
                 $subject = decodeHeader($orig_header->subject,false,false,true);
                 $subject = str_replace('"', "'", $subject);
                 $subject = trim($subject);
@@ -948,7 +992,7 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
                 $body = '';
                 $strip_sigs = getPref($data_dir, $username, 'strip_sigs');
                 foreach ($rewrap_body as $line) {
-                    if ($strip_sigs && substr($line,0,3) == '-- ') {
+                    if ($strip_sigs && rtrim($line, "\r\n") == '-- ') {
                         break;
                     }
                     if (preg_match("/^(>+)/", $line, $matches)) {
@@ -1019,7 +1063,8 @@ function getAttachments($message, &$composeMessage, $passed_id, $entities, $imap
                     $filename = $message->getFilename();
                     break;
             }
-            $filename = str_replace('&#32;', ' ', decodeHeader($filename));
+//FIXME: added three args to the following, so as to set the last one to TRUE, to mimick a fix in 1.4.21 (#2994865), but didn't test this (note that in 1.4.21, the 2nd and 3rd args are FALSE, but here in this code, they weren't being specified (thus defaulting to TRUE), so I don't know if that means this code is outdated and should have been changed to FALSE, FALSE or if this code is completely different and the addition of the TRUE for arg #4 is wrong
+            $filename = str_replace('&#32;', ' ', decodeHeader($filename, true, true, true));
             if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
                     function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode')) {
                 $filename =  call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode', $filename);
@@ -1140,28 +1185,40 @@ function showInputForm ($session, $values=false) {
     // to do; SquirrelMail itself will add the final "return true".
     // Onsubmit text is enclosed inside of double quotes, so plugins
     // need to quote accordingly.
+    //
+    // Also, plugin authors should try to retain compatibility with
+    // the Compose Extras plugin by resetting its compose submit
+    // counter when preventing form submit.  Use this code: 
+    // if (your-code-here) { submit_count = 0; return false; }
+    //
     if (checkForJavascript()) {
-        $onsubmit_text = ' onsubmit="';
         if (empty($compose_onsubmit))
             $compose_onsubmit = array();
         else if (!is_array($compose_onsubmit))
             $compose_onsubmit = array($compose_onsubmit);
 
+        $onsubmit_text = '';
         foreach ($compose_onsubmit as $text) {
             $text = trim($text);
-            if (substr($text, -1) != ';' && substr($text, -1) != '}')
-                $text .= '; ';
-            $onsubmit_text .= $text;
+            if (!empty($text)) {
+                if (substr($text, -1) != ';' && substr($text, -1) != '}')
+                    $text .= '; ';
+                $onsubmit_text .= $text;
+            }
         }
 
+        if (!empty($onsubmit_text))
 //FIXME: DON'T ECHO HTML FROM CORE!
-        echo $onsubmit_text . ' return true;"';
+            echo ' onsubmit="' . $onsubmit_text . ' return true;"';
     }
 
 
 //FIXME: NO HTML IN CORE!
     echo ">\n";
 
+//FIXME: DON'T ECHO HTML FROM CORE!
+    echo addHidden('smtoken', sm_generate_security_token());
+
 //FIXME: DON'T ECHO HTML FROM CORE!
     echo addHidden('startMessage', $startMessage);
 
@@ -1576,6 +1633,8 @@ function deliverMessage(&$composeMessage, $draft=false) {
 
     $reply_to = '';
     $reply_to  = $idents[$identity]['reply_to'];
+    if ($reply_to && strpos($reply_to, '@') === FALSE)
+        $reply_to .= '@' . $domain;
     
     $from_addr = build_from_header($identity);
     $rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);