From 4d4264cdcd0faa510d256637e7b3d0ab9b4d4646 Mon Sep 17 00:00:00 2001 From: thomascube Date: Thu, 10 Aug 2006 07:07:43 +0000 Subject: Fixed charset problems with folder renaming --- CHANGELOG | 5 +++ program/include/main.inc | 4 +- program/include/rcube_imap.inc | 38 ++++++++++------- program/js/app.js | 70 +++++++++++++++---------------- program/js/common.js | 7 ++++ program/steps/mail/search.inc | 6 +-- program/steps/settings/manage_folders.inc | 34 ++++++++++----- 7 files changed, 98 insertions(+), 66 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 190949e80..a9973fb34 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ CHANGELOG RoundCube Webmail --------------------------- +2006/08/10 (thomasb) +---------- +- Fixed charset problems with folder renaming + + 2006/08/04 (thomasb) ---------- - Fixed Bug in saving identities (Ticket #1483915) diff --git a/program/include/main.inc b/program/include/main.inc index b7f28c4e4..59b827763 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -909,7 +909,7 @@ function rcube_charset_convert($str, $from, $to=NULL) // convert string to UTF-8 if ($from=='UTF-7') $str = rcube_charset_convert(UTF7DecodeString($str), 'ISO-8859-1'); - else if ($from=='ISO-8859-1' && function_exists('utf8_encode')) + else if (($from=='ISO-8859-1') && function_exists('utf8_encode')) $str = utf8_encode($str); else if ($from!='UTF-8') { @@ -919,7 +919,7 @@ function rcube_charset_convert($str, $from, $to=NULL) // encode string for output if ($to=='UTF-7') - return UTF7EncodeString($str); + return UTF7EncodeString(rcube_charset_convert($str, 'UTF-8', 'ISO-8859-1')); else if ($to=='ISO-8859-1' && function_exists('utf8_decode')) return utf8_decode($str); else if ($to!='UTF-8') diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc index 7f74eb7d9..9c93f628a 100644 --- a/program/include/rcube_imap.inc +++ b/program/include/rcube_imap.inc @@ -26,7 +26,6 @@ */ require_once('lib/imap.inc'); require_once('lib/mime.inc'); -require_once('lib/utf7.inc'); /** @@ -835,9 +834,9 @@ class rcube_imap $search = (!empty($charset) ? "CHARSET $charset " : '') . sprintf("%s {%d}\r\n%s", $criteria, strlen($str), $str); $results = $this->_search_index($mailbox, $search); - // try search without charset (probably not supported by server) - if (empty($results)) - $results = $this->_search_index($mailbox, "$criteria $str"); + // try search with ISO charset (should be supported by server) + if (empty($results) && !empty($charset) && $charset!='ISO-8859-1') + $results = $this->search($mbox_name, $criteria, rcube_charset_convert($str, $charset, 'ISO-8859-1'), 'ISO-8859-1'); return $results; } @@ -1231,7 +1230,11 @@ class rcube_imap /** - * create a new mailbox on the server and register it in local cache + * Create a new mailbox on the server and register it in local cache + * + * @param string New mailbox name (as utf-7 string) + * @param boolean True if the new mailbox should be subscribed + * @param string Name of the created mailbox, false on error */ function create_mailbox($name, $subscribe=FALSE) { @@ -1240,12 +1243,10 @@ class rcube_imap // replace backslashes $name = preg_replace('/[\\\]+/', '-', $name); - $name_enc = UTF7EncodeString($name); - // reduce mailbox name to 100 chars - $name_enc = substr($name_enc, 0, 100); + $name = substr($name, 0, 100); - $abs_name = $this->_mod_mailbox($name_enc); + $abs_name = $this->_mod_mailbox($name); $a_mailbox_cache = $this->get_cache('mailboxes'); if (strlen($abs_name) && (!is_array($a_mailbox_cache) || !in_array_nocase($abs_name, $a_mailbox_cache))) @@ -1253,14 +1254,18 @@ class rcube_imap // try to subscribe it if ($subscribe) - $this->subscribe($name_enc); + $this->subscribe($name); return $result ? $name : FALSE; } /** - * set a new name to an existing mailbox + * Set a new name to an existing mailbox + * + * @param string Mailbox to rename (as utf-7 string) + * @param string New mailbox name (as utf-7 string) + * @param string Name of the renames mailbox, false on error */ function rename_mailbox($mbox_name, $new_name) { @@ -1270,21 +1275,24 @@ class rcube_imap $name = preg_replace('/[\\\]+/', '-', $new_name); // encode mailbox name and reduce it to 100 chars - $name_enc = substr(UTF7EncodeString($new_name), 0, 100); + $name = substr($new_name, 0, 100); // make absolute path $mailbox = $this->_mod_mailbox($mbox_name); - $abs_name = $this->_mod_mailbox($name_enc); - + $abs_name = $this->_mod_mailbox($name); + if (strlen($abs_name)) $result = iil_C_RenameFolder($this->conn, $mailbox, $abs_name); - + // clear cache if ($result) { $this->clear_message_cache($mailbox.'.msg'); $this->clear_cache('mailboxes'); } + + // try to subscribe it + $this->subscribe($name); return $result ? $name : FALSE; } diff --git a/program/js/app.js b/program/js/app.js index f8c5aaf54..e1d02fde2 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -711,7 +711,7 @@ function rcube_webmail() if (this.env.mailbox==this.env.drafts_mailbox) { this.set_busy(true); - location.href = this.env.comm_path+'&_action=compose&_draft_uid='+uid+'&_mbox='+escape(this.env.mailbox); + location.href = this.env.comm_path+'&_action=compose&_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox); } else this.show_message(uid); @@ -880,7 +880,7 @@ function rcube_webmail() { var uid; if (uid = this.get_single_uid()) - url += '&_draft_uid='+uid+'&_mbox='+escape(this.env.mailbox); + url += '&_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox); } // modify url if we're in addressbook else if (this.task=='addressbook') @@ -992,7 +992,7 @@ function rcube_webmail() if (uid = this.get_single_uid()) { this.set_busy(true); - location.href = this.env.comm_path+'&_action=compose&_reply_uid='+uid+'&_mbox='+escape(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''); + location.href = this.env.comm_path+'&_action=compose&_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''); } break; @@ -1001,7 +1001,7 @@ function rcube_webmail() if (uid = this.get_single_uid()) { this.set_busy(true); - location.href = this.env.comm_path+'&_action=compose&_forward_uid='+uid+'&_mbox='+escape(this.env.mailbox); + location.href = this.env.comm_path+'&_action=compose&_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox); } break; @@ -1009,7 +1009,7 @@ function rcube_webmail() var uid; if (uid = this.get_single_uid()) { - this.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+escape(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : '')); + this.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : '')); if (this.printwin) setTimeout(this.ref+'.printwin.focus()', 20); } @@ -1019,7 +1019,7 @@ function rcube_webmail() var uid; if (uid = this.get_single_uid()) { - this.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+this.env.uid+'&_mbox='+escape(this.env.mailbox)); + this.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox)); if (this.sourcewin) setTimeout(this.ref+'.sourcewin.focus()', 20); } @@ -1034,7 +1034,7 @@ function rcube_webmail() if (!props && this.gui_objects.qsearchbox) props = this.gui_objects.qsearchbox.value; if (props) - this.qsearch(escape(props), this.env.mailbox); + this.qsearch(urlencode(props), this.env.mailbox); break; // reset quicksearch @@ -1261,7 +1261,7 @@ function rcube_webmail() if (this.env.mailbox==this.env.drafts_mailbox) { this.set_busy(true); - location.href = this.env.comm_path+'&_action=compose&_draft_uid='+id+'&_mbox='+escape(this.env.mailbox); + location.href = this.env.comm_path+'&_action=compose&_draft_uid='+id+'&_mbox='+urlencode(this.env.mailbox); } else { @@ -1521,7 +1521,7 @@ function rcube_webmail() if (id) { this.set_busy(true, 'loading'); - target.location.href = this.env.comm_path+'&_action=show&_uid='+id+'&_mbox='+escape(this.env.mailbox)+add_url; + target.location.href = this.env.comm_path+'&_action=show&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url; } }; @@ -1593,7 +1593,7 @@ function rcube_webmail() if (mbox) { this.set_busy(true, 'loading'); - target.location.href = this.env.comm_path+'&_mbox='+escape(mbox)+(page ? '&_page='+page : '')+add_url; + target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url; } }; @@ -1605,7 +1605,7 @@ function rcube_webmail() this.clear_message_list(); // send request to server - var url = '_mbox='+escape(mbox)+(page ? '&_page='+page : ''); + var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : ''); this.set_busy(true, 'loading'); this.http_request('list', url+add_url, true); }; @@ -1657,7 +1657,7 @@ function rcube_webmail() } // send request to server - var url = '_mbox='+escape(mbox); + var url = '_mbox='+urlencode(mbox); this.http_request('expunge', url+add_url, lock); }; @@ -1679,7 +1679,7 @@ function rcube_webmail() } // send request to server - var url = '_mbox='+escape(mbox); + var url = '_mbox='+urlencode(mbox); this.http_request('purge', url+add_url, lock); return true; }; @@ -1736,7 +1736,7 @@ function rcube_webmail() this.set_busy(true, 'movingmessage'); } // send request to server - this.http_request('moveto', '_uid='+a_uids.join(',')+'&_mbox='+escape(this.env.mailbox)+'&_target_mbox='+escape(mbox)+'&_from='+(this.env.action ? this.env.action : ''), lock); + this.http_request('moveto', '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+'&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : ''), lock); }; this.permanently_remove_messages = function() { @@ -1767,7 +1767,7 @@ function rcube_webmail() if (new_row) this.select_row(new_row.uid,false,false); // send request to server - this.http_request('delete', '_uid='+a_uids.join(',')+'&_mbox='+escape(this.env.mailbox)+'&_from='+(this.env.action ? this.env.action : '')); + this.http_request('delete', '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+'&_from='+(this.env.action ? this.env.action : '')); } @@ -2209,7 +2209,7 @@ function rcube_webmail() this.remove_attachment = function(name) { if (name) - this.http_request('remove-attachment', '_file='+escape(name)); + this.http_request('remove-attachment', '_file='+urlencode(name)); return true; }; @@ -2722,7 +2722,7 @@ function rcube_webmail() name = form.elements['_folder_name'].value; if (name) - this.http_request('create-folder', '_name='+escape(name), true); + this.http_request('create-folder', '_name='+urlencode(name), true); else if (form.elements['_folder_name']) form.elements['_folder_name'].focus(); }; @@ -2745,7 +2745,7 @@ function rcube_webmail() } if (oldname && newname) - this.http_request('rename-folder', '_folder_oldname='+escape(oldname)+'&_folder_newname='+escape(newname)); + this.http_request('rename-folder', '_folder_oldname='+urlencode(oldname)+'&_folder_newname='+urlencode(newname)); }; @@ -2767,7 +2767,7 @@ function rcube_webmail() if (id && (row = document.getElementById(id))) { this.name_input = document.createElement('INPUT'); - this.name_input.value = this.env.subscriptionrows[id]; + this.name_input.value = this.env.subscriptionrows[id][1]; this.name_input.style.width = '100%'; this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); }; @@ -2786,7 +2786,7 @@ function rcube_webmail() { var cell = this.name_input ? this.name_input.parentNode : null; if (cell && this.edit_folder) - cell.innerHTML = this.env.subscriptionrows[this.edit_folder]; + cell.innerHTML = this.env.subscriptionrows[this.edit_folder][1]; this.edit_folder = null; }; @@ -2802,7 +2802,7 @@ function rcube_webmail() { var newname = this.name_input ? this.name_input.value : null; if (this.edit_folder && newname) - this.http_request('rename-folder', '_folder_oldname='+escape(this.env.subscriptionrows[this.edit_folder])+'&_folder_newname='+escape(newname)); + this.http_request('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname)); } // escape else if (key==27) @@ -2817,12 +2817,12 @@ function rcube_webmail() this.reset_folder_rename(); if (folder) - this.http_request('delete-folder', '_mboxes='+escape(folder)); + this.http_request('delete-folder', '_mboxes='+urlencode(folder)); }; // add a new folder to the subscription list by cloning a folder row - this.add_folder_row = function(name, replace) + this.add_folder_row = function(name, display_name, replace) { name = name.replace('\\',""); if (!this.gui_objects.subscriptionlist) @@ -2853,10 +2853,10 @@ function rcube_webmail() } // add to folder/row-ID map - this.env.subscriptionrows[row.id] = name; + this.env.subscriptionrows[row.id] = [name, display_name]; // set folder name - row.cells[0].innerHTML = name; + row.cells[0].innerHTML = display_name; if (row.cells[1] && row.cells[1].firstChild.tagName=='INPUT') { row.cells[1].firstChild.value = name; @@ -2881,13 +2881,13 @@ function rcube_webmail() // replace an existing table row with a new folder line - this.replace_folder_row = function(newfolder, oldfolder) + this.replace_folder_row = function(oldfolder, newfolder, display_name) { var id = this.get_folder_row_id(oldfolder); var row = document.getElementById(id); // replace an existing table row (if found) - this.add_folder_row(newfolder, row); + this.add_folder_row(newfolder, display_name, row); this.env.subscriptionrows[id] = null; // rename folder in rename-folder dropdown @@ -2898,7 +2898,7 @@ function rcube_webmail() { if (elm.options[i].value == oldfolder) { - elm.options[i].text = newfolder; + elm.options[i].text = display_name; elm.options[i].value = newfolder; break; } @@ -2943,7 +2943,7 @@ function rcube_webmail() if ((form = this.gui_objects.editform) && form.elements['_unsubscribed']) this.change_subscription('_unsubscribed', '_subscribed', 'subscribe'); else if (folder) - this.http_request('subscribe', '_mboxes='+escape(folder)); + this.http_request('subscribe', '_mboxes='+urlencode(folder)); }; @@ -2953,7 +2953,7 @@ function rcube_webmail() if ((form = this.gui_objects.editform) && form.elements['_subscribed']) this.change_subscription('_subscribed', '_unsubscribed', 'unsubscribe'); else if (folder) - this.http_request('unsubscribe', '_mboxes='+escape(folder)); + this.http_request('unsubscribe', '_mboxes='+urlencode(folder)); }; @@ -2987,7 +2987,7 @@ function rcube_webmail() list_to[index] = new Option(a_folders[n]); } - this.http_request(action, '_mboxes='+escape(a_folders.join(','))); + this.http_request(action, '_mboxes='+urlencode(a_folders.join(','))); } } @@ -2997,7 +2997,7 @@ function rcube_webmail() this.get_folder_row_id = function(folder) { for (var id in this.env.subscriptionrows) - if (this.env.subscriptionrows[id]==folder) + if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder) break; return id; @@ -3522,8 +3522,8 @@ function rcube_webmail() // send request if (request_obj) { - // prompt('request', this.env.comm_path+'&_action='+escape(action)+'&'+querystring); - console('HTTP request: '+this.env.comm_path+'&_action='+escape(action)+'&'+querystring); + // prompt('request', this.env.comm_path+'&_action='+urlencode(action)+'&'+querystring); + console('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring); if (lock) this.set_busy(true); @@ -3532,7 +3532,7 @@ function rcube_webmail() request_obj.__action = action; request_obj.onerror = function(o){ rcube_webmail_client.http_error(o); }; request_obj.oncomplete = function(o){ rcube_webmail_client.http_response(o); }; - request_obj.GET(this.env.comm_path+'&_action='+escape(action)+'&'+querystring); + request_obj.GET(this.env.comm_path+'&_action='+action+'&'+querystring); } }; diff --git a/program/js/common.js b/program/js/common.js index 7ac3dc807..b0dc5564a 100644 --- a/program/js/common.js +++ b/program/js/common.js @@ -343,6 +343,13 @@ function find_in_array() } +// make a string URL safe +function urlencode(str) +{ + return window.encodeURI ? encodeURI(str).replace(/&/g, '%26') : escape(str); +} + + // get any type of html objects by id/name function rcube_find_object(id, d) { diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc index 517ef3008..e1690ee63 100644 --- a/program/steps/mail/search.inc +++ b/program/steps/mail/search.inc @@ -19,9 +19,9 @@ $REMOTE_REQUEST = TRUE; $IMAP->set_page(1); $_SESSION['page'] = 1; -// search query comes in with ISO encoding because javascript escape() -// uses ISO-8859-1. Better handling for that will follow. -$imap_charset = 'ISO-8859-1'; +// using encodeURI with javascript "should" give us +// a correctly UTF-8 encoded query string +$imap_charset = 'UTF-8'; // get search string $str = get_input_value('_search', RCUBE_INPUT_GET); diff --git a/program/steps/settings/manage_folders.inc b/program/steps/settings/manage_folders.inc index 457fcb5d2..2fbc780ca 100644 --- a/program/steps/settings/manage_folders.inc +++ b/program/steps/settings/manage_folders.inc @@ -47,11 +47,13 @@ else if ($_action=='unsubscribe') else if ($_action=='create-folder') { if (!empty($_GET['_name'])) - $create = $IMAP->create_mailbox(trim(get_input_value('_name', RCUBE_INPUT_GET)), TRUE); + $create = $IMAP->create_mailbox(trim(get_input_value('_name', RCUBE_INPUT_GET, FALSE, 'UTF-7')), TRUE); if ($create && $REMOTE_REQUEST) { - $commands = sprintf("this.add_folder_row('%s')", rep_specialchars_output($create, 'js')); + $commands = sprintf("this.add_folder_row('%s','%s')", + rep_specialchars_output($create, 'js'), + rep_specialchars_output(rcube_charset_convert($create, 'UTF-7'), 'js')); rcube_remote_response($commands); } else if (!$create && $REMOTE_REQUEST) @@ -67,13 +69,15 @@ else if ($_action=='create-folder') else if ($_action=='rename-folder') { if (!empty($_GET['_folder_oldname']) && !empty($_GET['_folder_newname'])) - $rename = $IMAP->rename_mailbox(get_input_value('_folder_oldname', RCUBE_INPUT_GET), trim(get_input_value('_folder_newname', RCUBE_INPUT_GET))); - + $rename = $IMAP->rename_mailbox(get_input_value('_folder_oldname', RCUBE_INPUT_GET), trim(get_input_value('_folder_newname', RCUBE_INPUT_GET, FALSE, 'UTF-7'))); + if ($rename && $REMOTE_REQUEST) { - $commands = sprintf("this.replace_folder_row('%s','%s');", - addslashes(rep_specialchars_output($rename, 'js')), - rep_specialchars_output($_GET['_folder_oldname'], 'js')); + $commands = sprintf("this.replace_folder_row('%s','%s','%s');", + rep_specialchars_output($_GET['_folder_oldname'], 'js'), + rep_specialchars_output($rename, 'js'), + rep_specialchars_output(rcube_charset_convert($rename, 'UTF-7'), 'js')); + rcube_remote_response($commands); } else if (!$rename && $REMOTE_REQUEST) @@ -135,6 +139,8 @@ function rcube_subscription_form($attrib) // get folders from server + $IMAP->clear_cache('mailboxes'); + $a_unsubscribed = $IMAP->list_unsubscribed(); $a_subscribed = $IMAP->list_mailboxes(); $a_js_folders = array(); @@ -154,18 +160,24 @@ function rcube_subscription_form($attrib) // create list of available folders foreach ($a_unsubscribed as $i => $folder) { + $subscribed = in_array($folder, $a_subscribed); $protected = ($CONFIG['protect_default_folders'] == TRUE && in_array($folder,$CONFIG['default_imap_folders'])); $zebra_class = $i%2 ? 'even' : 'odd'; $folder_js = rep_specialchars_output($folder, 'js'); + $folder_js_enc = rep_specialchars_output(rcube_charset_convert($folder, 'UTF-7'), 'js'); if (!$protected) - $a_js_folders['rcmrow'.($i+1)] = $folder_js; + $a_js_folders['rcmrow'.($i+1)] = array($folder_js, $folder_js_enc); - $out .= sprintf('%s%s', + $out .= sprintf('%s', $i+1, $zebra_class, - rep_specialchars_output(rcube_charset_convert($folder, 'UTF-7', 'UTF-8'), 'html', 'all'), - $checkbox_subscribe->show(in_array($folder, $a_subscribed)?$folder:'', array('value' => $folder, 'disabled' => $protected))); + rep_specialchars_output(rcube_charset_convert($folder, 'UTF-7'), 'html', 'all')); + + if ($protected) + $out .= ' '.($subscribed ? '•' : '-').''; + else + $out .= ''.$checkbox_subscribe->show($subscribed?$folder:'', array('value' => $folder)).''; // add rename and delete buttons if (!$protected) -- cgit v1.2.3