From c21f95f626e66b052309103e74d445300f68bdab Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 31 Jul 2015 05:20:50 -0400
Subject: [PATCH] Fix bug where new messages weren't added to the list in search mode

---
 program/lib/Roundcube/rcube_imap.php |  270 ++++++++++++++++++-----------------------------------
 1 files changed, 92 insertions(+), 178 deletions(-)

diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index a1fd874..9a4843d 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -1,6 +1,6 @@
 <?php
 
-/*
+/**
  +-----------------------------------------------------------------------+
  | This file is part of the Roundcube Webmail client                     |
  | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
@@ -95,7 +95,6 @@
         }
     }
 
-
     /**
      * Magic getter for backward compat.
      *
@@ -107,7 +106,6 @@
             return $this->{$name};
         }
     }
-
 
     /**
      * Connect to an IMAP server
@@ -203,7 +201,6 @@
         return false;
     }
 
-
     /**
      * Close IMAP connection.
      * Usually done on script shutdown
@@ -215,7 +212,6 @@
             $this->mcache->close();
         }
     }
-
 
     /**
      * Check connection state, connect if not connected.
@@ -238,7 +234,6 @@
         return $this->is_connected();
     }
 
-
     /**
      * Checks IMAP connection.
      *
@@ -248,7 +243,6 @@
     {
         return $this->conn->connected();
     }
-
 
     /**
      * Returns code of last error
@@ -260,7 +254,6 @@
         return $this->conn->errornum;
     }
 
-
     /**
      * Returns text of last error
      *
@@ -270,7 +263,6 @@
     {
         return $this->conn->error;
     }
-
 
     /**
      * Returns code of last command response
@@ -301,7 +293,6 @@
         }
     }
 
-
     /**
      * Activate/deactivate debug mode
      *
@@ -313,23 +304,21 @@
         $this->conn->setDebug($dbg, array($this, 'debug_handler'));
     }
 
-
     /**
      * Set internal folder reference.
      * All operations will be perfomed on this folder.
      *
-     * @param  string $folder Folder name
+     * @param string $folder Folder name
      */
     public function set_folder($folder)
     {
         $this->folder = $folder;
     }
 
-
     /**
      * Save a search result for future message listing methods
      *
-     * @param  array  $set  Search set, result from rcube_imap::get_search_set():
+     * @param array $set Search set, result from rcube_imap::get_search_set():
      *                      0 - searching criteria, string
      *                      1 - search result, rcube_result_index|rcube_result_thread
      *                      2 - searching character set, string
@@ -352,7 +341,6 @@
         }
     }
 
-
     /**
      * Return the saved search set as hash array
      *
@@ -372,7 +360,6 @@
             $this->search_sorted,
         );
     }
-
 
     /**
      * Returns the IMAP server's capability.
@@ -397,14 +384,13 @@
         return $_SESSION[$sess_key];
     }
 
-
     /**
      * Checks the PERMANENTFLAGS capability of the current folder
      * and returns true if the given flag is supported by the IMAP server
      *
-     * @param   string  $flag Permanentflag name
+     * @param string $flag Permanentflag name
      *
-     * @return  boolean True if this flag is supported
+     * @return boolean True if this flag is supported
      */
     public function check_permflag($flag)
     {
@@ -415,11 +401,10 @@
         return $imap_flag && !empty($perm_flags) && in_array_nocase($imap_flag, $perm_flags);
     }
 
-
     /**
      * Returns PERMANENTFLAGS of the specified folder
      *
-     * @param  string $folder Folder name
+     * @param string $folder Folder name
      *
      * @return array Flags
      */
@@ -447,25 +432,22 @@
         return $permflags;
     }
 
-
     /**
      * Returns the delimiter that is used by the IMAP server for folder separation
      *
-     * @return  string  Delimiter string
-     * @access  public
+     * @return string Delimiter string
      */
     public function get_hierarchy_delimiter()
     {
         return $this->delimiter;
     }
 
-
     /**
      * Get namespace
      *
      * @param string $name Namespace array index: personal, other, shared, prefix
      *
-     * @return  array  Namespace data
+     * @return array Namespace data
      */
     public function get_namespace($name = null)
     {
@@ -478,7 +460,6 @@
         unset($ns['prefix']);
         return $ns;
     }
-
 
     /**
      * Sets delimiter and namespaces
@@ -560,7 +541,6 @@
         $_SESSION['imap_delimiter'] = $this->delimiter;
     }
 
-
     /**
      * Get message count for a specific folder
      *
@@ -570,7 +550,7 @@
      * @param  boolean $status  Enables storing folder status info (max UID/count),
      *                          required for folder_status()
      *
-     * @return int     Number of messages
+     * @return int Number of messages
      */
     public function count($folder='', $mode='ALL', $force=false, $status=true)
     {
@@ -581,29 +561,31 @@
         return $this->countmessages($folder, $mode, $force, $status);
     }
 
-
     /**
-     * protected method for getting nr of messages
+     * Protected method for getting number of messages
      *
-     * @param string  $folder  Folder name
-     * @param string  $mode    Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
-     * @param boolean $force   Force reading from server and update cache
-     * @param boolean $status  Enables storing folder status info (max UID/count),
-     *                         required for folder_status()
+     * @param string  $folder    Folder name
+     * @param string  $mode      Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
+     * @param boolean $force     Force reading from server and update cache
+     * @param boolean $status    Enables storing folder status info (max UID/count),
+     *                           required for folder_status()
+     * @param boolean $no_search Ignore current search result
      *
      * @return int Number of messages
      * @see rcube_imap::count()
      */
-    protected function countmessages($folder, $mode='ALL', $force=false, $status=true)
+    protected function countmessages($folder, $mode = 'ALL', $force = false, $status = true, $no_search = false)
     {
         $mode = strtoupper($mode);
 
-        // count search set, assume search set is always up-to-date (don't check $force flag)
-        if ($this->search_string && $folder == $this->folder && ($mode == 'ALL' || $mode == 'THREADS')) {
+        // Count search set, assume search set is always up-to-date (don't check $force flag)
+        // @TODO: this could be handled in more reliable way, e.g. a separate method
+        //        maybe in rcube_imap_search
+        if (!$no_search && $this->search_string && $folder == $this->folder) {
             if ($mode == 'ALL') {
                 return $this->search_set->count_messages();
             }
-            else {
+            else if ($mode == 'THREADS') {
                 return $this->search_set->count();
             }
         }
@@ -696,7 +678,6 @@
         return (int)$count;
     }
 
-
     /**
      * Public method for listing message flags
      *
@@ -731,7 +712,6 @@
         return $result;
     }
 
-
     /**
      * Public method for listing headers
      *
@@ -741,7 +721,7 @@
      * @param   string   $sort_order Sort order [ASC|DESC]
      * @param   int      $slice      Number of slice items to extract from result array
      *
-     * @return  array    Indexed array with message header objects
+     * @return array Indexed array with message header objects
      */
     public function list_messages($folder='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0)
     {
@@ -752,7 +732,6 @@
         return $this->_list_messages($folder, $page, $sort_field, $sort_order, $slice);
     }
 
-
     /**
      * protected method for listing message headers
      *
@@ -762,8 +741,8 @@
      * @param   string   $sort_order Sort order [ASC|DESC]
      * @param   int      $slice      Number of slice items to extract from result array
      *
-     * @return  array    Indexed array with message header objects
-     * @see     rcube_imap::list_messages
+     * @return array Indexed array with message header objects
+     * @see rcube_imap::list_messages
      */
     protected function _list_messages($folder='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0)
     {
@@ -806,16 +785,15 @@
         return array_values($a_msg_headers);
     }
 
-
     /**
      * protected method for listing message headers using threads
      *
-     * @param   string   $folder     Folder name
-     * @param   int      $page       Current page to list
-     * @param   int      $slice      Number of slice items to extract from result array
+     * @param string $folder Folder name
+     * @param int    $page   Current page to list
+     * @param int    $slice  Number of slice items to extract from result array
      *
-     * @return  array    Indexed array with message header objects
-     * @see     rcube_imap::list_messages
+     * @return array Indexed array with message header objects
+     * @see rcube_imap::list_messages
      */
     protected function list_thread_messages($folder, $page, $slice=0)
     {
@@ -833,7 +811,7 @@
     /**
      * Method for fetching threads data
      *
-     * @param  string $folder Folder name
+     * @param string $folder Folder name
      *
      * @return rcube_imap_thread Thread data object
      */
@@ -857,11 +835,10 @@
         return $this->icache['threads'] = $result;
     }
 
-
     /**
      * Method for direct fetching of threads data
      *
-     * @param  string $folder Folder name
+     * @param string $folder Folder name
      *
      * @return rcube_imap_thread Thread data object
      */
@@ -876,7 +853,6 @@
             $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
     }
 
-
     /**
      * protected method for fetching threaded messages headers
      *
@@ -885,7 +861,7 @@
      * @param int                 $page       List page number
      * @param int                 $slice      Number of threads to slice
      *
-     * @return array  Messages headers
+     * @return array Messages headers
      */
     protected function fetch_thread_headers($folder, $threads, $page, $slice=0)
     {
@@ -915,13 +891,12 @@
         return array_values($a_msg_headers);
     }
 
-
     /**
      * protected method for setting threaded messages flags:
      * depth, has_children and unread_children
      *
-     * @param  array               $headers  Reference to headers array indexed by message UID
-     * @param  rcube_result_thread $threads  Threads data object
+     * @param array               $headers  Reference to headers array indexed by message UID
+     * @param rcube_result_thread $threads  Threads data object
      *
      * @return array Message headers array indexed by message UID
      */
@@ -947,7 +922,6 @@
         }
     }
 
-
     /**
      * protected method for listing a set of message headers (search results)
      *
@@ -955,7 +929,7 @@
      * @param   int      $page     Current page to list
      * @param   int      $slice    Number of slice items to extract from result array
      *
-     * @return  array    Indexed array with message header objects
+     * @return array Indexed array with message header objects
      */
     protected function list_search_messages($folder, $page, $slice=0)
     {
@@ -1140,7 +1114,6 @@
         }
     }
 
-
     /**
      * protected method for listing a set of threaded message headers (search results)
      *
@@ -1148,7 +1121,7 @@
      * @param   int      $page       Current page to list
      * @param   int      $slice      Number of slice items to extract from result array
      *
-     * @return  array    Indexed array with message header objects
+     * @return array Indexed array with message header objects
      * @see rcube_imap::list_search_messages()
      */
     protected function list_search_thread_messages($folder, $page, $slice=0)
@@ -1163,7 +1136,6 @@
 
         return $this->fetch_thread_headers($folder, clone $this->search_set, $page, $slice);
     }
-
 
     /**
      * Fetches messages headers (by UID)
@@ -1212,7 +1184,6 @@
         return $a_msg_headers;
     }
 
-
     /**
      * Returns current status of a folder (compared to the last time use)
      *
@@ -1232,7 +1203,7 @@
         $old = $this->get_folder_stats($folder);
 
         // refresh message count -> will update
-        $this->countmessages($folder, 'ALL', true);
+        $this->countmessages($folder, 'ALL', true, true, true);
 
         $result = 0;
 
@@ -1260,7 +1231,6 @@
         return $result;
     }
 
-
     /**
      * Stores folder statistic data in session
      * @TODO: move to separate DB table (cache?)
@@ -1273,7 +1243,6 @@
     {
         $_SESSION['folders'][$folder][$name] = $data;
     }
-
 
     /**
      * Gets folder statistic data
@@ -1290,7 +1259,6 @@
 
         return array();
     }
-
 
     /**
      * Return sorted list of message UIDs
@@ -1369,7 +1337,6 @@
         return $this->index_direct($folder, $this->sort_field, $this->sort_order);
     }
 
-
     /**
      * Return sorted list of message UIDs ignoring current search settings.
      * Doesn't uses cache by default.
@@ -1437,7 +1404,6 @@
         return $index;
     }
 
-
     /**
      * Return index of threaded message UIDs
      *
@@ -1468,7 +1434,6 @@
         return $threads;
     }
 
-
     /**
      * Sort threaded result, using THREAD=REFS method if available.
      * If not, use any method and re-sort the result in THREAD=REFS way.
@@ -1497,7 +1462,6 @@
             $threads->revert();
         }
     }
-
 
     /**
      * Invoke search request to IMAP server
@@ -1574,7 +1538,6 @@
         return $results;
     }
 
-
     /**
      * Direct (real and simple) SEARCH request (without result sorting and caching).
      *
@@ -1608,7 +1571,6 @@
 
         return $index;
     }
-
 
     /**
      * protected search method
@@ -1686,7 +1648,6 @@
         return $messages;
     }
 
-
     /**
      * Converts charset of search criteria string
      *
@@ -1726,7 +1687,6 @@
         return $res;
     }
 
-
     /**
      * Refresh saved search set
      *
@@ -1758,7 +1718,6 @@
             }
         }
     }
-
 
     /**
      * Return message headers object of a specific message
@@ -1798,13 +1757,12 @@
         return $headers;
     }
 
-
     /**
      * Fetch message headers and body structure from the IMAP server and build
-     * an object structure similar to the one generated by PEAR::Mail_mimeDecode
+     * an object structure.
      *
-     * @param int     $uid      Message UID to fetch
-     * @param string  $folder   Folder to read from
+     * @param int    $uid    Message UID to fetch
+     * @param string $folder Folder to read from
      *
      * @return object rcube_message_header Message data
      */
@@ -1883,8 +1841,8 @@
                 $structure[1] = $m[2];
             }
             else {
-                // Try to parse the message using Mail_mimeDecode package
-                // We need a better solution, Mail_mimeDecode parses message
+                // Try to parse the message using rcube_mime_decode.
+                // We need a better solution, it parses message
                 // in memory, which wouldn't work for very big messages,
                 // (it uses up to 10x more memory than the message size)
                 // it's also buggy and not actively developed
@@ -1924,7 +1882,6 @@
         return $this->icache['message'] = $headers;
     }
 
-
     /**
      * Build message part object
      *
@@ -1932,7 +1889,7 @@
      * @param int    $count
      * @param string $parent
      */
-    protected function structure_part($part, $count=0, $parent='', $mime_headers=null)
+    protected function structure_part($part, $count = 0, $parent = '', $mime_headers = null)
     {
         $struct = new rcube_message_part;
         $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count";
@@ -1957,6 +1914,16 @@
             for ($i=1; $i<count($part); $i++) {
                 if (!is_array($part[$i])) {
                     $struct->ctype_secondary = strtolower($part[$i]);
+
+                    // read content type parameters
+                    if (is_array($part[$i+1])) {
+                        $struct->ctype_parameters = array();
+                        for ($j=0; $j<count($part[$i+1]); $j+=2) {
+                            $param = strtolower($part[$i+1][$j]);
+                            $struct->ctype_parameters[$param] = $part[$i+1][$j+1];
+                        }
+                    }
+
                     break;
                 }
             }
@@ -2140,14 +2107,13 @@
         return $struct;
     }
 
-
     /**
      * Set attachment filename from message part structure
      *
-     * @param  rcube_message_part $part    Part object
-     * @param  string             $headers Part's raw headers
+     * @param rcube_message_part $part    Part object
+     * @param string             $headers Part's raw headers
      */
-    protected function set_part_filename(&$part, $headers=null)
+    protected function set_part_filename(&$part, $headers = null)
     {
         if (!empty($part->d_parameters['filename'])) {
             $filename_mime = $part->d_parameters['filename'];
@@ -2275,11 +2241,10 @@
         }
     }
 
-
     /**
      * Get charset name from message structure (first part)
      *
-     * @param  array $structure Message structure
+     * @param array $structure Message structure
      *
      * @return string Charset name
      */
@@ -2308,7 +2273,8 @@
      *
      * @return string Message/part body if not printed
      */
-    public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0, $formatted=true)
+    public function get_message_part($uid, $part = 1, $o_part = null, $print = null, $fp = null,
+        $skip_charset_conv = false, $max_bytes = 0, $formatted = true)
     {
         if (!$this->check_connection()) {
             return null;
@@ -2360,42 +2326,41 @@
         return $body;
     }
 
-
     /**
      * Returns the whole message source as string (or saves to a file)
      *
-     * @param int      $uid Message UID
-     * @param resource $fp  File pointer to save the message
+     * @param int      $uid  Message UID
+     * @param resource $fp   File pointer to save the message
+     * @param string   $part Optional message part ID
      *
      * @return string Message source string
      */
-    public function get_raw_body($uid, $fp=null)
+    public function get_raw_body($uid, $fp=null, $part = null)
     {
         if (!$this->check_connection()) {
             return null;
         }
 
         return $this->conn->handlePartBody($this->folder, $uid,
-            true, null, null, false, $fp);
+            true, $part, null, false, $fp);
     }
-
 
     /**
      * Returns the message headers as string
      *
-     * @param int $uid  Message UID
+     * @param int    $uid  Message UID
+     * @param string $part Optional message part ID
      *
      * @return string Message headers string
      */
-    public function get_raw_headers($uid)
+    public function get_raw_headers($uid, $part = null)
     {
         if (!$this->check_connection()) {
             return null;
         }
 
-        return $this->conn->fetchPartHeader($this->folder, $uid, true);
+        return $this->conn->fetchPartHeader($this->folder, $uid, true, $part);
     }
-
 
     /**
      * Sends the whole message source to stdout
@@ -2411,7 +2376,6 @@
 
         $this->conn->handlePartBody($this->folder, $uid, true, null, null, true, null, $formatted);
     }
-
 
     /**
      * Set message flag to one or several messages
@@ -2472,7 +2436,6 @@
         return $result;
     }
 
-
     /**
      * Append a mail message (source) to a specific folder
      *
@@ -2529,7 +2492,6 @@
 
         return $saved;
     }
-
 
     /**
      * Move a message from one folder to another
@@ -2608,7 +2570,6 @@
         return $moved;
     }
 
-
     /**
      * Copy a message from one folder to another
      *
@@ -2644,7 +2605,6 @@
 
         return $copied;
     }
-
 
     /**
      * Mark messages as deleted and expunge them
@@ -2702,7 +2662,6 @@
 
         return $deleted;
     }
-
 
     /**
      * Send IMAP expunge command and clear cache
@@ -2826,15 +2785,14 @@
         return $a_mboxes;
     }
 
-
     /**
      * Method for direct folders listing (LSUB)
      *
-     * @param   string  $root   Optional root folder
-     * @param   string  $name   Optional name pattern
+     * @param string $root Optional root folder
+     * @param string $name Optional name pattern
      *
-     * @return  array   List of subscribed folders
-     * @see     rcube_imap::list_folders_subscribed()
+     * @return array List of subscribed folders
+     * @see rcube_imap::list_folders_subscribed()
      */
     public function list_folders_subscribed_direct($root='', $name='*')
     {
@@ -2871,7 +2829,7 @@
             if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) {
                 foreach ($a_folders as $idx => $folder) {
                     if (($opts = $this->conn->data['LIST'][$folder])
-                        && in_array('\\NonExistent', $opts)
+                        && in_array_nocase('\\NonExistent', $opts)
                     ) {
                         $this->conn->unsubscribe($folder);
                         unset($a_folders[$idx]);
@@ -2894,7 +2852,6 @@
 
         return $a_folders;
     }
-
 
     /**
      * Get a list of all folders available on the server
@@ -2964,15 +2921,14 @@
         return $a_mboxes;
     }
 
-
     /**
      * Method for direct folders listing (LIST)
      *
-     * @param   string  $root   Optional root folder
-     * @param   string  $name   Optional name pattern
+     * @param string $root Optional root folder
+     * @param string $name Optional name pattern
      *
-     * @return  array   List of folders
-     * @see     rcube_imap::list_folders()
+     * @return array List of folders
+     * @see rcube_imap::list_folders()
      */
     public function list_folders_direct($root='', $name='*')
     {
@@ -2996,13 +2952,12 @@
         return $result;
     }
 
-
     /**
      * Fix folders list by adding folders from other namespaces.
      * Needed on some servers eg. Courier IMAP
      *
-     * @param array  $result  Reference to folders list
-     * @param string $type    Listing type (ext-subscribed, subscribed or all)
+     * @param array  $result Reference to folders list
+     * @param string $type   Listing type (ext-subscribed, subscribed or all)
      */
     protected function list_folders_update(&$result, $type = null)
     {
@@ -3052,7 +3007,6 @@
         }
     }
 
-
     /**
      * Filter the given list of folders according to access rights
      *
@@ -3078,7 +3032,6 @@
         return $a_folders;
     }
 
-
     /**
      * Get mailbox quota information
      *
@@ -3094,7 +3047,6 @@
 
         return false;
     }
-
 
     /**
      * Get folder size (size of all messages in a folder)
@@ -3119,7 +3071,6 @@
         return $result;
     }
 
-
     /**
      * Subscribe to a specific folder(s)
      *
@@ -3133,7 +3084,6 @@
         return $this->change_subscription($folders, 'subscribe');
     }
 
-
     /**
      * Unsubscribe folder(s)
      *
@@ -3146,7 +3096,6 @@
         // let this common function do the main work
         return $this->change_subscription($folders, 'unsubscribe');
     }
-
 
     /**
      * Create a new folder on the server and register it in local cache
@@ -3165,16 +3114,6 @@
 
         $result = $this->conn->createFolder($folder, $type ? array("\\" . ucfirst($type)) : null);
 
-        // it's quite often situation that we're trying to create and subscribe
-        // a folder that already exist, but is unsubscribed
-        if (!$result) {
-            if ($this->get_response_code() == rcube_storage::ALREADYEXISTS
-                || preg_match('/already exists/i', $this->get_error_str())
-            ) {
-                $result = true;
-            }
-        }
-
         // try to subscribe it
         if ($result) {
             // clear cache
@@ -3187,7 +3126,6 @@
 
         return $result;
     }
-
 
     /**
      * Set a new name to an existing folder
@@ -3248,7 +3186,6 @@
         return $result;
     }
 
-
     /**
      * Remove folder from server
      *
@@ -3296,7 +3233,6 @@
         return $result;
     }
 
-
     /**
      * Detect special folder associations stored in storage backend
      */
@@ -3341,7 +3277,6 @@
         return array_merge($result, $special);
     }
 
-
     /**
      * Set special folder associations stored in storage backend
      */
@@ -3380,7 +3315,6 @@
         return true;
     }
 
-
     /**
      * Checks if folder exists and is subscribed
      *
@@ -3408,7 +3342,7 @@
         if ($subscription) {
             // It's possible we already called LIST command, check LIST data
             if (!empty($this->conn->data['LIST']) && !empty($this->conn->data['LIST'][$folder])
-                && in_array('\\Subscribed', $this->conn->data['LIST'][$folder])
+                && in_array_nocase('\\Subscribed', $this->conn->data['LIST'][$folder])
             ) {
                 $a_folders = array($folder);
             }
@@ -3433,7 +3367,6 @@
 
         return false;
     }
-
 
     /**
      * Returns the namespace where the folder is in
@@ -3464,7 +3397,6 @@
 
         return 'personal';
     }
-
 
     /**
      * Modify folder name according to namespace.
@@ -3504,7 +3436,6 @@
         return $folder;
     }
 
-
     /**
      * Gets folder attributes from LIST response, e.g. \Noselect, \Noinferiors
      *
@@ -3536,7 +3467,6 @@
 
         return is_array($opts) ? $opts : array();
     }
-
 
     /**
      * Gets connection (and current folder) data: UIDVALIDITY, EXISTS, RECENT,
@@ -3576,7 +3506,6 @@
 
         return $data;
     }
-
 
     /**
      * Returns extended information about the folder
@@ -3673,7 +3602,6 @@
         return $options;
     }
 
-
     /**
      * Synchronizes messages cache.
      *
@@ -3685,7 +3613,6 @@
             $mcache->synchronize($folder);
         }
     }
-
 
     /**
      * Get message header names for rcube_imap_generic::fetchHeader(s)
@@ -3738,7 +3665,6 @@
         return $this->conn->setACL($folder, $user, $acl);
     }
 
-
     /**
      * Removes any <identifier,rights> pair for the
      * specified user from the ACL for the specified
@@ -3763,7 +3689,6 @@
         return $this->conn->deleteACL($folder, $user);
     }
 
-
     /**
      * Returns the access control list for folder (GETACL)
      *
@@ -3784,7 +3709,6 @@
 
         return $this->conn->getACL($folder);
     }
-
 
     /**
      * Returns information about what rights can be granted to the
@@ -3809,7 +3733,6 @@
         return $this->conn->listRights($folder, $user);
     }
 
-
     /**
      * Returns the set of rights that the current user has to
      * folder (MYRIGHTS)
@@ -3831,7 +3754,6 @@
 
         return $this->conn->myRights($folder);
     }
-
 
     /**
      * Sets IMAP metadata/annotations (SETMETADATA/SETANNOTATION)
@@ -3866,7 +3788,6 @@
         return false;
     }
 
-
     /**
      * Unsets IMAP metadata/annotations (SETMETADATA/SETANNOTATION)
      *
@@ -3899,7 +3820,6 @@
 
         return false;
     }
-
 
     /**
      * Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION)
@@ -3951,7 +3871,13 @@
 
             // @TODO: Honor MAXSIZE and DEPTH options
             foreach ($queries as $attrib => $entry) {
-                if ($result = $this->conn->getAnnotation($folder, $entry, $attrib)) {
+                $result = $this->conn->getAnnotation($folder, $entry, $attrib);
+
+                // an error, invalidate any previous getAnnotation() results
+                if (!is_array($result)) {
+                    return null;
+                }
+                else {
                     foreach ($result as $fldr => $data) {
                         $res[$fldr] = array_merge((array) $res[$fldr], $data);
                     }
@@ -3966,7 +3892,6 @@
 
         return null;
     }
-
 
     /**
      * Converts the METADATA extension entry name into the correct
@@ -4097,7 +4022,6 @@
         }
     }
 
-
     /**
      * Getter for messages cache object
      */
@@ -4116,7 +4040,6 @@
         return $this->mcache;
     }
 
-
     /**
      * Clears the messages cache.
      *
@@ -4129,7 +4052,6 @@
             $mcache->clear($folder, $uids);
         }
     }
-
 
     /**
      * Delete outdated cache entries
@@ -4159,7 +4081,6 @@
             $this->sort_order = strtoupper($sort_order) == 'DESC' ? 'DESC' : 'ASC';
         }
     }
-
 
     /**
      * Sort folders first by default folders and then in alphabethical order
@@ -4247,12 +4168,11 @@
         }
     }
 
-
     /**
      * Find UID of the specified message sequence ID
      *
-     * @param int    $id       Message (sequence) ID
-     * @param string $folder   Folder name
+     * @param int    $id     Message (sequence) ID
+     * @param string $folder Folder name
      *
      * @return int Message UID
      */
@@ -4276,7 +4196,6 @@
 
         return $uid;
     }
-
 
     /**
      * Subscribe/unsubscribe a list of folders and update local cache
@@ -4310,7 +4229,6 @@
         return $updated;
     }
 
-
     /**
      * Increde/decrese messagecount for a specific folder
      */
@@ -4341,7 +4259,6 @@
         return true;
     }
 
-
     /**
      * Remove messagecount of a specific folder from cache
      */
@@ -4359,7 +4276,6 @@
             $this->update_cache('messagecount', $a_folder_cache);
         }
     }
-
 
     /**
      * Converts date string/object into IMAP date/time format
@@ -4382,7 +4298,6 @@
 
         return $date->format('d-M-Y H:i:s O');
     }
-
 
     /**
      * This is our own debug handler for the IMAP connection
@@ -4513,7 +4428,7 @@
         return $this->mod_folder($folder, $mode);
     }
 
-    public function mailbox_attributes($folder, $force=false)
+    public function mailbox_attributes($folder, $force = false)
     {
         return $this->folder_attributes($folder, $force);
     }
@@ -4533,9 +4448,8 @@
         return $this->folder_sync($folder);
     }
 
-    public function expunge($folder='', $clear_cache=true)
+    public function expunge($folder = '', $clear_cache = true)
     {
         return $this->expunge_folder($folder, $clear_cache);
     }
-
 }

--
Gitblit v1.9.1