diff --git a/CHANGELOG b/CHANGELOG index 47c80ed3b..a890c5451 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ CHANGELOG Roundcube Webmail - Fix E_DEPRECATED warning when using Auth_SASL::factory() (#5401) - Fix bug where names of downloaded files could be malformed when derived from the message subject (#5404) - Fix so "All" messages selection is resetted on search reset (#5413) +- Fix bug where folder creation could fail if personal namespace contained more than one entry (#5403) RELEASE 1.2.1 ------------- diff --git a/program/include/rcmail.php b/program/include/rcmail.php index e3a5b36cc..7a9d1a97b 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -1465,7 +1465,7 @@ class rcmail extends rcube $prefix = ''; if (!$path) { $n_folder = $folder; - $folder = $this->storage->mod_folder($folder); + $folder = $this->storage->mod_folder($folder); if ($n_folder != $folder) { $prefix = substr($n_folder, 0, -strlen($folder)); @@ -1499,10 +1499,11 @@ class rcmail extends rcube if (!isset($arrFolders[$currentFolder])) { $arrFolders[$currentFolder] = array( - 'id' => $path, - 'name' => rcube_charset::convert($currentFolder, 'UTF7-IMAP'), + 'id' => $path, + 'name' => rcube_charset::convert($currentFolder, 'UTF7-IMAP'), 'virtual' => $virtual, - 'folders' => array()); + 'folders' => array() + ); } else { $arrFolders[$currentFolder]['virtual'] = $virtual; diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index 4a9fdb741..f8c8c3dd3 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -454,7 +454,8 @@ class rcube_imap extends rcube_storage return isset($ns[$name]) ? $ns[$name] : null; } - unset($ns['prefix']); + unset($ns['prefix_in'], $ns['prefix_out']); + return $ns; } @@ -528,10 +529,24 @@ class rcube_imap extends rcube_storage } } - // Find personal namespace prefix for mod_folder() - // Prefix can be removed when there is only one personal namespace - if (is_array($this->namespace['personal']) && count($this->namespace['personal']) == 1) { - $this->namespace['prefix'] = $this->namespace['personal'][0][0]; + // Find personal namespace prefix(es) for self::mod_folder() + if (is_array($this->namespace['personal']) && !empty($this->namespace['personal'])) { + // There can be more than one namespace root, + // - for prefix_out get the first one but only + // if there is only one root + // - for prefix_in get the first one but only + // if there is no non-prefixed namespace root (#5403) + $roots = array(); + foreach ($this->namespace['personal'] as $ns) { + $roots[] = $ns[0]; + } + + if (!in_array('', $roots)) { + $this->namespace['prefix_in'] = $roots[0]; + } + if (count($roots) == 1) { + $this->namespace['prefix_out'] = $roots[0]; + } } $_SESSION['imap_namespace'] = $this->namespace; @@ -3474,26 +3489,23 @@ class rcube_imap extends rcube_storage } /** - * Modify folder name according to namespace. + * Modify folder name according to personal namespace prefix. * For output it removes prefix of the personal namespace if it's possible. * For input it adds the prefix. Use it before creating a folder in root * of the folders tree. * * @param string $folder Folder name - * @param string $mode Mode name (out/in) + * @param string $mode Mode name (out/in) * * @return string Folder name */ public function mod_folder($folder, $mode = 'out') { - if (!strlen($folder)) { - return $folder; - } + $prefix = $this->namespace['prefix_' . $mode]; // see set_env() - $prefix = $this->namespace['prefix']; // see set_env() - $prefix_len = strlen($prefix); - - if (!$prefix_len) { + if ($prefix === null || $prefix === '' + || !($prefix_len = strlen($prefix)) || !strlen($folder) + ) { return $folder; } @@ -3502,13 +3514,12 @@ class rcube_imap extends rcube_storage if (substr($folder, 0, $prefix_len) === $prefix) { return substr($folder, $prefix_len); } - } - // add prefix for input (e.g. folder creation) - else { - return $prefix . $folder; + + return $folder; } - return $folder; + // add prefix for input (e.g. folder creation) + return $prefix . $folder; } /**