Happy New Year
[squirrelmail.git] / class / deliver / Deliver.class.php
index 1cb3826d4f667ff902377b67a9f99d421461a9b5..d145cefeb0e0beb01998fc625a9fc8c4b911737c 100644 (file)
@@ -7,7 +7,7 @@
  * a delivery backend.
  *
  * @author Marc Groot Koerkamp
- * @copyright 1999-2019 The SquirrelMail Project Team
+ * @copyright 1999-2020 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -596,7 +596,15 @@ class Deliver {
         $rn = "\r\n";
 
         /* This creates an RFC 822 date */
-        $date = date('D, j M Y H:i:s ', time()) . $this->timezone();
+        $now = time();
+        $now_date = date('D, j M Y H:i:s ', $now) . $this->timezone();
+        // TODO: Do we really want to preserve possibly old date?  Date header should always have "now"... but here is not where this decision should be made -- the caller really should blank out $rfc822_header->date even for drafts being re-edited or sent
+        if (!empty($rfc822_header->date) && $rfc822_header->date != -1)
+            $message_date = date('D, j M Y H:i:s ', $rfc822_header->date) . $this->timezone();
+        else {
+            $message_date = $now_date;
+            $rfc822_header->date = $now;
+        }
 
         /* Create a message-id */
         $message_id = 'MESSAGE ID GENERATION ERROR! PLEASE CONTACT SQUIRRELMAIL DEVELOPERS';
@@ -653,7 +661,7 @@ class Deliver {
             if (!isset($hide_auth_header) || !$hide_auth_header)
                 $header[] = "        (SquirrelMail authenticated user $username)" . $rn;
             $header[] = "        by $SERVER_NAME with HTTP;" . $rn;
-            $header[] = "        $date" . $rn;
+            $header[] = "        $now_date" . $rn;
           }
         }
 
@@ -677,12 +685,7 @@ class Deliver {
             $rfc822_header->references = $references;
         }
 
-        if (!empty($rfc822_header->date) && $rfc822_header->date != -1) {
-            $header[] = 'Date: '. $rfc822_header->date . $rn;
-        } else {
-            $header[] = "Date: $date" . $rn;
-            $rfc822_header->date = $date;
-        }
+        $header[] = "Date: $message_date" . $rn;
 
         $header[] = 'Subject: '.encodeHeader($rfc822_header->subject) . $rn;
         $header[] = 'From: '. $rfc822_header->getAddr_s('from',",$rn ",true) . $rn;
@@ -835,6 +838,11 @@ class Deliver {
       */
     function foldLine($header, $soft_wrap=78, $indent='', $hard_wrap=998) {
 
+        // allow folding after the initial colon and space?
+        // (only supported if the header name is within the $soft_wrap limit)
+        //
+        $allow_fold_after_header_name = FALSE;
+
         // the "hard" token list can be altered if desired,
         // for example, by adding ":"
         // (in the future, we can take optional arguments
@@ -866,8 +874,27 @@ class Deliver {
 
         $CRLF = "\r\n";
 
+        // switch that helps compact the last line, pasting it at the
+        // end of the one before if the one before is already over the
+        // soft limit and it wouldn't go over the hard limit
+        //
+        $pull_last_line_up_if_second_to_last_is_already_over_soft_limit = FALSE;
+
+
+        // ----- end configurable behaviors -----
+
+
         $folded_header = '';
 
+        // if we want to prevent a wrap right after the
+        // header name, make note of the position here
+        //
+        if (!$allow_fold_after_header_name
+         && ($header_name_end_pos = strpos($header, ':'))
+         && strlen($header) > $header_name_end_pos + 1
+         && in_array($header{$header_name_end_pos + 1}, $whitespace))
+            $header_name_end_pos++;
+
         // if using an indent string, reduce wrap limits by its size
         //
         if (!empty($indent)) {
@@ -888,6 +915,13 @@ class Deliver {
                 //
                 if ($pos = strrpos($soft_wrapped_line, $token))
                 {
+
+                    // make sure proposed fold isn't forbidden
+                    //
+                    if (!$allow_fold_after_header_name
+                     && $pos === $header_name_end_pos)
+                        continue;
+
                     $new_fold = substr($header, 0, $pos);
 
                     // make sure proposed fold doesn't create a blank line
@@ -949,8 +983,24 @@ class Deliver {
             // what is left is no more than the hard wrap limit, we'll
             // simply take the whole thing
             //
-            if (strlen($header) <= strlen($hard_wrapped_line))
+            if (strlen($header) <= $hard_wrap) {
+
+                // if the header has been folded at least once before now,
+                // let's see if we can add the remaining chunk to the last
+                // fold (this is mainly just aesthetic)
+                //
+                if ($pull_last_line_up_if_second_to_last_is_already_over_soft_limit
+                 && strlen($folded_header)
+                 // last fold is conveniently in $new_fold
+                 && strlen($new_fold) + strlen($header) <= $hard_wrap) {
+                    // $last_fold = substr(substr($folded_header, 0, -(strlen($CRLF) + strlen($indent))), 
+                    // remove CRLF and indentation and paste the rest of the header on
+                    $folded_header = substr($folded_header, 0, -(strlen($CRLF) + strlen($indent))) . $header;
+                    $header = '';
+                }
+
                 break;
+            }
 
             // otherwise, we can't quit yet - look for a "hard" token
             // as close to the end of the hard wrap limit as possible
@@ -1015,7 +1065,9 @@ class Deliver {
                     // and add a space after the fold if not immediately
                     // followed by a whitespace character in the next part
                     //
-                    $folded_header .= substr($header, 0, $pos + 1) . $CRLF;
+                    // $new_fold is used above, it's assumed we update it upon every fold action
+                    $new_fold = substr($header, 0, $pos + 1);
+                    $folded_header .= $new_fold . $CRLF;
 
                     // don't go beyond end of $header, though
                     //
@@ -1038,7 +1090,9 @@ class Deliver {
             // finally, we just couldn't find anything to fold on, so we
             // have to just cut it off at the hard limit
             //
-            $folded_header .= $hard_wrapped_line . $CRLF;
+            // $new_fold is used above, it's assumed we update it upon every fold action
+            $new_fold = $hard_wrapped_line;
+            $folded_header .= $new_fold . $CRLF;
 
             // is there more?
             //