From b8f9ba7d47e90c3f499b39145a97a1cf64dd09ef Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 14 Oct 2016 08:48:19 +0200 Subject: [PATCH] Fix bug where deleting folders with subfolders could fail in some cases (#5466) --- CHANGELOG | 1 + program/lib/Roundcube/rcube_imap.php | 49 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b9738c722b6..7f61598876e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,7 @@ CHANGELOG Roundcube Webmail - Fix regression where creation of default folders wasn't functioning without prefix (#5460) - Enigma: Fix bug where last records on keys list were hidden (#5461) - Enigma: Fix key search with keyword containing non-ascii characters (#5459) +- Fix bug where deleting folders with subfolders could fail in some cases (#5466) RELEASE 1.2.2 ------------- diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index cbc9f3b1c60..2d137e4dade 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -3293,49 +3293,48 @@ public function rename_folder($folder, $new_name) } /** - * Remove folder from server + * Remove folder (with subfolders) from the server * * @param string $folder Folder name * - * @return boolean True on success + * @return boolean True on success, False on failure */ function delete_folder($folder) { - $delm = $this->get_hierarchy_delimiter(); - if (!$this->check_connection()) { return false; } - // get list of folders - if ((strpos($folder, '%') === false) && (strpos($folder, '*') === false)) { - $sub_mboxes = $this->list_folders('', $folder . $delm . '*'); - } - else { - $sub_mboxes = $this->list_folders(); - } - - // send delete command to server - $result = $this->conn->deleteFolder($folder); - - if ($result) { - // unsubscribe folder - $this->conn->unsubscribe($folder); + $delm = $this->get_hierarchy_delimiter(); - foreach ($sub_mboxes as $c_mbox) { - if (strpos($c_mbox, $folder.$delm) === 0) { - $this->conn->unsubscribe($c_mbox); - if ($this->conn->deleteFolder($c_mbox)) { - $this->clear_message_cache($c_mbox); + // get list of sub-folders or all folders + // if folder name contains special characters + $path = strspn($folder, '%*') > 0 ? ($folder . $delm) : ''; + $sub_mboxes = $this->list_folders('', $path . '*'); + + // According to RFC3501 deleting a \Noselect folder + // with subfolders may fail. To workaround this we delete + // subfolders first (in reverse order) (#5466) + if (!empty($sub_mboxes)) { + foreach (array_reverse($sub_mboxes) as $mbox) { + if (strpos($mbox, $folder . $delm) === 0) { + if ($this->conn->deleteFolder($mbox)) { + $this->conn->unsubscribe($mbox); + $this->clear_message_cache($mbox); } } } + } - // clear folder-related cache + // delete the folder + if ($result = $this->conn->deleteFolder($folder)) { + // and unsubscribe it + $this->conn->unsubscribe($folder); $this->clear_message_cache($folder); - $this->clear_cache('mailboxes', true); } + $this->clear_cache('mailboxes', true); + return $result; }