From 9a8a86efcae2c3c5ff36f71cbba7acd5ce3d4c6f Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Sat, 26 May 2012 04:34:54 -0400
Subject: [PATCH] Catch DateTime* exceptions (#1488497) - skipping buggy timezones

---
 program/include/rcube_imap_generic.php |  125 ++++++++++++++++++++++++++++++++---------
 1 files changed, 96 insertions(+), 29 deletions(-)

diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 3482439..29dff86 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -7,7 +7,10 @@
  | This file is part of the Roundcube Webmail client                     |
  | Copyright (C) 2005-2010, The Roundcube Dev Team                       |
  | Copyright (C) 2011, Kolab Systems AG                                  |
- | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | Licensed under the GNU General Public License version 3 or            |
+ | any later version with exceptions for skins & plugins.                |
+ | See the README file for a full license statement.                     |
  |                                                                       |
  | PURPOSE:                                                              |
  |   Provide alternative IMAP library that doesn't rely on the standard  |
@@ -56,6 +59,55 @@
     public $mdn_to;
     public $others = array();
     public $flags = array();
+
+    // map header to rcube_message_header object property
+    private $obj_headers = array(
+        'date'      => 'date',
+        'from'      => 'from',
+        'to'        => 'to',
+        'subject'   => 'subject',
+        'reply-to'  => 'replyto',
+        'cc'        => 'cc',
+        'bcc'       => 'bcc',
+        'content-transfer-encoding' => 'encoding',
+        'in-reply-to'               => 'in_reply_to',
+        'content-type'              => 'ctype',
+        'references'                => 'references',
+        'return-receipt-to'         => 'mdn_to',
+        'disposition-notification-to' => 'mdn_to',
+        'x-confirm-reading-to'      => 'mdn_to',
+        'message-id'                => 'messageID',
+        'x-priority'                => 'priority',
+    );
+
+    /**
+     * Returns header value
+     */
+    public function get($name)
+    {
+        $name = strtolower($name);
+
+        if (isset($this->obj_headers[$name])) {
+            return $this->{$this->obj_headers[$name]};
+        }
+
+        return $this->others[$name];
+    }
+
+    /**
+     * Sets header value
+     */
+    public function set($name, $value)
+    {
+        $name = strtolower($name);
+
+        if (isset($this->obj_headers[$name])) {
+            $this->{$this->obj_headers[$name]} = $value;
+        }
+        else {
+            $this->others[$name] = $value;
+        }
+    }
 }
 
 // For backward compatibility with cached messages (#1486602)
@@ -1231,7 +1283,7 @@
     {
         $num_in_trash = $this->countMessages($mailbox);
         if ($num_in_trash > 0) {
-            $res = $this->delete($mailbox, '1:*');
+            $res = $this->flag($mailbox, '1:*', 'DELETED');
         }
 
         if ($res) {
@@ -1349,12 +1401,16 @@
                         $folders[$mailbox] = array();
                     }
 
-                    // Add to options array
-                    if (empty($this->data['LIST'][$mailbox]))
-                        $this->data['LIST'][$mailbox] = $opts;
-                    else if (!empty($opts))
-                        $this->data['LIST'][$mailbox] = array_unique(array_merge(
-                            $this->data['LIST'][$mailbox], $opts));
+                    // store LSUB options only if not empty, this way
+                    // we can detect a situation when LIST doesn't return specified folder
+                    if (!empty($opts) || $cmd == 'LIST') {
+                        // Add to options array
+                        if (empty($this->data['LIST'][$mailbox]))
+                            $this->data['LIST'][$mailbox] = $opts;
+                        else if (!empty($opts))
+                            $this->data['LIST'][$mailbox] = array_unique(array_merge(
+                                $this->data['LIST'][$mailbox], $opts));
+                    }
                 }
                 // * STATUS <mailbox> (<result>)
                 else if ($cmd == 'STATUS') {
@@ -1450,7 +1506,7 @@
 
         // Invoke SEARCH as a fallback
         $index = $this->search($mailbox, 'ALL UNSEEN', false, array('COUNT'));
-        if (!$index->isError()) {
+        if (!$index->is_error()) {
             return $index->count();
         }
 
@@ -1556,6 +1612,11 @@
             return new rcube_result_index($mailbox);
         }
 
+        // RFC 5957: SORT=DISPLAY
+        if (($field == 'FROM' || $field == 'TO') && $this->getCapability('SORT=DISPLAY')) {
+            $field = 'DISPLAY' . $field;
+        }
+
         // message IDs
         if (!empty($add))
             $add = $this->compressMessageSet($add);
@@ -1638,7 +1699,7 @@
 
         // If ESEARCH is supported always use ALL
         // but not when items are specified or using simple id2uid search
-        if (empty($items) && ((int) $criteria != $criteria)) {
+        if (empty($items) && preg_match('/[^0-9]/', $criteria)) {
             $items = array('ALL');
         }
 
@@ -2067,9 +2128,10 @@
                 $result[$id]->subject   = '';
                 $result[$id]->messageID = 'mid:' . $id;
 
-                $lines = array();
-                $line  = substr($line, strlen($m[0]) + 2);
-                $ln    = 0;
+                $headers = null;
+                $lines   = array();
+                $line    = substr($line, strlen($m[0]) + 2);
+                $ln      = 0;
 
                 // get complete entry
                 while (preg_match('/\{([0-9]+)\}\r\n$/', $line, $m)) {
@@ -3249,28 +3311,30 @@
 	    if (!is_array($a)) {
             return false;
         }
+
+        if (empty($part)) {
+		    return $a;
+	    }
+
+        $ctype = is_string($a[0]) && is_string($a[1]) ? $a[0] . '/' . $a[1] : '';
+
+        if (strcasecmp($ctype, 'message/rfc822') == 0) {
+            $a = $a[8];
+        }
+
 	    if (strpos($part, '.') > 0) {
-		    $original_part = $part;
-		    $pos = strpos($part, '.');
-		    $rest = substr($original_part, $pos+1);
-		    $part = substr($original_part, 0, $pos);
-		    if ((strcasecmp($a[0], 'message') == 0) && (strcasecmp($a[1], 'rfc822') == 0)) {
-			    $a = $a[8];
-		    }
+		    $orig_part = $part;
+		    $pos       = strpos($part, '.');
+		    $rest      = substr($orig_part, $pos+1);
+		    $part      = substr($orig_part, 0, $pos);
+
 		    return self::getStructurePartArray($a[$part-1], $rest);
 	    }
-        else if ($part>0) {
-		    if (!is_array($a[0]) && (strcasecmp($a[0], 'message') == 0)
-                && (strcasecmp($a[1], 'rfc822') == 0)) {
-			    $a = $a[8];
-		    }
+        else if ($part > 0) {
 		    if (is_array($a[$part-1]))
                 return $a[$part-1];
 		    else
                 return $a;
-	    }
-        else if (($part == 0) || (empty($part))) {
-		    return $a;
 	    }
     }
 
@@ -3602,13 +3666,16 @@
         if ($string === null) {
             return 'NIL';
         }
+
         if ($string === '') {
             return '""';
         }
+
         // atom-string (only safe characters)
-        if (!$force_quotes && !preg_match('/[\x00-\x20\x22\x28-\x2A\x5B-\x5D\x7B\x7D\x80-\xFF]/', $string)) {
+        if (!$force_quotes && !preg_match('/[\x00-\x20\x22\x25\x28-\x2A\x5B-\x5D\x7B\x7D\x80-\xFF]/', $string)) {
             return $string;
         }
+
         // quoted-string
         if (!preg_match('/[\r\n\x00\x80-\xFF]/', $string)) {
             return '"' . addcslashes($string, '\\"') . '"';

--
Gitblit v1.9.1