From cb3ea1443ee52b0e323869cdf36db658762f58c9 Mon Sep 17 00:00:00 2001 From: Raoul Bhatia Date: Sun, 27 Oct 2013 08:34:42 +0100 Subject: Deny access to all files not containing a . (dot) to block access to different README, ChangeLog, etc. files of various skins and plugins. Do not check case for default README/INSTALL/LICENE files. --- .htaccess | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.htaccess b/.htaccess index dc6e62f38..10af3094e 100644 --- a/.htaccess +++ b/.htaccess @@ -28,10 +28,17 @@ RewriteEngine On RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico # security rules RewriteRule \.git - [F] -RewriteRule ^/?(README(.md)?|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ - [F] -RewriteRule ^/?(SQL|bin) - [F] +RewriteRule ^/?(README(.md)?|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ - [NC,F] +RewriteRule ^/?(SQL|bin) - [NC,F] +# deny access to all files not containing a "." (dot) +# to block access to different README, ChangeLog, etc. files +# of various skins and plugins. + +Deny from all + + SetOutputFilter DEFLATE -- cgit v1.2.3 From e769a7b588dde028a41cde482995601b63ad87b2 Mon Sep 17 00:00:00 2001 From: cmcnulty Date: Wed, 30 Oct 2013 20:45:26 -0500 Subject: need to reset shift_start on control select reproduce steps: shift-select some messages, hold down control and select another message. hold down shift+control and select more messages - desired behavior, two separate ranges of selected messages. (consistent with outlook/thunderbird/windows explorer) --- program/js/list.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/program/js/list.js b/program/js/list.js index b2d4f8a63..24ee38c4d 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -790,8 +790,10 @@ select_row: function(id, mod_key, with_mouse) break; case CONTROL_KEY: - if (with_mouse) + if (with_mouse) { + this.shift_start = id; this.highlight_row(id, true); + } break; case CONTROL_SHIFT_KEY: -- cgit v1.2.3 From 04fbc555b939ef2e427f02b9765ae66f85a5b918 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 4 Nov 2013 21:34:17 +0100 Subject: Code improvements --- program/js/app.js | 141 ++++++++++++++++++++---------------------------------- 1 file changed, 53 insertions(+), 88 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index 1f75e219c..f7fd7cea0 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -218,12 +218,8 @@ function rcube_webmail() // load messages this.command('list'); - } - if (this.gui_objects.qsearchbox) { - if (this.env.search_text != null) - this.gui_objects.qsearchbox.value = this.env.search_text; - $(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list && rcmail.message_list.blur(); }); + $(this.gui_objects.qsearchbox).val(this.env.search_text).focusin(function() { rcmail.message_list.blur(); }); } this.set_button_titles(); @@ -285,10 +281,10 @@ function rcube_webmail() return rcube_event.cancel(e); }); - // avoid textarea loosing focus when hitting the save-response button/link - for (var i=0; this.buttons['save-response'] && i < this.buttons['save-response'].length; i++) { - $('#'+this.buttons['save-response'][i].id).mousedown(function(e){ return rcube_event.cancel(e); }) - } + // avoid textarea loosing focus when hitting the save-response button/link + for (var i=0; this.buttons['save-response'] && i < this.buttons['save-response'].length; i++) { + $('#'+this.buttons['save-response'][i].id).mousedown(function(e){ return rcube_event.cancel(e); }) + } } document.onmouseup = function(e){ return p.doc_mouse_up(e); }; @@ -351,7 +347,7 @@ function rcube_webmail() this.env.contactfolders = $.extend($.extend({}, this.env.address_sources), this.env.contactgroups); this.enable_command('add', 'import', this.env.writable_source); - this.enable_command('list', 'listgroup', 'pushgroup', 'popgroup', 'listsearch', 'advanced-search', true); + this.enable_command('list', 'listgroup', 'pushgroup', 'popgroup', 'listsearch', 'search', 'reset-search', 'advanced-search', true); if (this.gui_objects.contactslist) { this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, @@ -369,8 +365,8 @@ function rcube_webmail() this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); }; document.onmouseup = function(e){ return p.doc_mouse_up(e); }; - if (this.gui_objects.qsearchbox) - $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); }); + + $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); }); this.update_group_commands(); this.command('list'); @@ -394,9 +390,6 @@ function rcube_webmail() this.init_contact_form(); } - if (this.gui_objects.qsearchbox) - this.enable_command('search', 'reset-search', true); - break; case 'settings': @@ -408,9 +401,6 @@ function rcube_webmail() else if (this.env.action == 'edit-identity' || this.env.action == 'add-identity') { this.enable_command('save', 'edit', 'toggle-editor', true); this.enable_command('delete', this.env.identities_level < 2); - - if (this.env.action == 'add-identity') - $("input[type='text']").first().select(); } else if (this.env.action == 'folders') { this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', true); @@ -419,7 +409,6 @@ function rcube_webmail() this.enable_command('save', 'folder-size', true); parent.rcmail.env.exists = this.env.messagecount; parent.rcmail.enable_command('purge', this.env.messagecount); - $("input[type='text']").first().select(); } else if (this.env.action == 'responses') { this.enable_command('add', true); @@ -445,7 +434,7 @@ function rcube_webmail() } else if (this.gui_objects.responseslist) { this.responses_list = new rcube_list_widget(this.gui_objects.responseslist, {multiselect:false, draggable:false, keyboard:false}); - this.responses_list.addEventListener('select', function(list){ + this.responses_list.addEventListener('select', function(list) { var win, id = list.get_single_selection(); p.enable_command('delete', !!id && $.inArray(id, p.env.readonly_responses) < 0); if (id && (win = p.get_frame_window(p.env.contentframe))) { @@ -489,6 +478,11 @@ function rcube_webmail() break; } + // select first input field in an edit form + if (this.gui_objects.editform) + $("input,select,textarea", this.gui_objects.editform) + .not(':hidden').not(':disabled').first().select(); + // unset contentframe variable if preview_pane is enabled if (this.env.contentframe && !$('#' + this.env.contentframe).is(':visible')) this.env.contentframe = null; @@ -4820,8 +4814,6 @@ function rcube_webmail() $('input.datepicker').datepicker(); } - $("input[type='text']:visible").first().focus(); - // Submit search form on Enter if (this.env.action == 'search') $(this.gui_objects.editform).append($('').hide()) @@ -5438,7 +5430,10 @@ function rcube_webmail() this.init_subscription_list = function() { - var p = this; + var p = this, delim = RegExp.escape(this.env.delimiter); + + this.last_sub_rx = RegExp('['+delim+']?[^'+delim+']+$'); + this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, {multiselect:false, draggable:true, keyboard:false, toggleselect:true}); this.subscription_list.addEventListener('select', function(o){ p.subscription_select(o); }); @@ -5449,6 +5444,7 @@ function rcube_webmail() row.obj.onmouseout = function() { p.unfocus_subscription(row.id); }; }; this.subscription_list.init(); + $('#mailboxroot') .mouseover(function(){ p.focus_subscription(this.id); }) .mouseout(function(){ p.unfocus_subscription(this.id); }) @@ -5456,9 +5452,7 @@ function rcube_webmail() this.focus_subscription = function(id) { - var row, folder, - delim = RegExp.escape(this.env.delimiter), - reg = RegExp('['+delim+']?[^'+delim+']+$'); + var row, folder; if (this.drag_active && this.env.mailbox && (row = document.getElementById(id))) if (this.env.subscriptionrows[id] && @@ -5466,8 +5460,8 @@ function rcube_webmail() ) { if (this.check_droptarget(folder) && !this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2] && - (folder != this.env.mailbox.replace(reg, '')) && - (!folder.startsWith(this.env.mailbox + this.env.delimiter)) + folder != this.env.mailbox.replace(this.last_sub_rx, '') && + !folder.startsWith(this.env.mailbox + this.env.delimiter) ) { this.env.dstfolder = folder; $(row).addClass('droptarget'); @@ -5480,7 +5474,8 @@ function rcube_webmail() var row = $('#'+id); this.env.dstfolder = null; - if (this.env.subscriptionrows[id] && row[0]) + + if (this.env.subscriptionrows[id] && row.length) row.removeClass('droptarget'); else $(this.subscription_list.frame).removeClass('droptarget'); @@ -5506,21 +5501,20 @@ function rcube_webmail() this.subscription_move_folder = function(list) { - var delim = RegExp.escape(this.env.delimiter), - reg = RegExp('['+delim+']?[^'+delim+']+$'); - - if (this.env.mailbox && this.env.dstfolder !== null && (this.env.dstfolder != this.env.mailbox) && - (this.env.dstfolder != this.env.mailbox.replace(reg, '')) + if (this.env.mailbox && this.env.dstfolder !== null && + this.env.dstfolder != this.env.mailbox && + this.env.dstfolder != this.env.mailbox.replace(this.last_sub_rx, '') ) { - reg = new RegExp('[^'+delim+']*['+delim+']', 'g'); - var basename = this.env.mailbox.replace(reg, ''), - newname = this.env.dstfolder === '' ? basename : this.env.dstfolder+this.env.delimiter+basename; + var path = this.env.mailbox.split(this.env.delimiter), + basename = path.pop(), + newname = this.env.dstfolder === '' ? basename : this.env.dstfolder + this.env.delimiter + basename; if (newname != this.env.mailbox) { this.http_post('rename-folder', {_folder_oldname: this.env.mailbox, _folder_newname: newname}, this.set_busy(true, 'foldermoving')); this.subscription_list.draglayer.hide(); } } + this.drag_active = false; this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder)); }; @@ -5642,7 +5636,7 @@ function rcube_webmail() tbody = this.gui_objects.subscriptionlist.tBodies[0], folders = this.env.subscriptionrows, id = this.get_folder_row_id(oldfolder), - regex = new RegExp('^'+RegExp.escape(oldfolder)), + prefix_len = oldfolder.length, subscribed = $('input[name="_subscribed[]"]', $('#'+id)).prop('checked'), // find subfolders of renamed folder list = this.get_subfolders(oldfolder); @@ -5667,7 +5661,7 @@ function rcube_webmail() row.after(tmprow); row = tmprow; // update folder index - name = name.replace(regex, newfolder); + name = newfolder + name.slice(prefix_len); $('input[name="_subscribed[]"]', row).val(name); this.env.subscriptionrows[id][0] = name; // update the name if level is changed @@ -5912,46 +5906,23 @@ function rcube_webmail() // mouse over button this.button_over = function(command, id) { - var n, button, obj, a_buttons = this.buttons[command], - len = a_buttons ? a_buttons.length : 0; - - for (n=0; n this.env.current_page)); - this.enable_command('previouspage', 'firstpage', (this.env.current_page > 1)); + this.enable_command('nextpage', 'lastpage', this.env.pagecount > this.env.current_page); + this.enable_command('previouspage', 'firstpage', this.env.current_page > 1); }; // mark a mailbox as selected and set environment variable @@ -6163,14 +6134,10 @@ function rcube_webmail() this.treelist.select(name); } else if (this.gui_objects.folderlist) { - var current_li, target_li; - - if ((current_li = $('li.selected', this.gui_objects.folderlist))) { - current_li.removeClass('selected').addClass('unfocused'); - } - if ((target_li = this.get_folder_li(name, prefix, encode))) { - $(target_li).removeClass('unfocused').addClass('selected'); - } + $('li.selected', this.gui_objects.folderlist) + .removeClass('selected').addClass('unfocused'); + $(this.get_folder_li(name, prefix, encode)) + .removeClass('unfocused').addClass('selected'); // trigger event hook this.triggerEvent('selectfolder', { folder:name, prefix:prefix }); @@ -6199,8 +6166,6 @@ function rcube_webmail() name = this.html_identifier(name, encode); return document.getElementById(prefix+name); } - - return null; }; // for reordering column array (Konqueror workaround) -- cgit v1.2.3 From 88934b6132ac22da5a66724943837bf5cae82779 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 5 Nov 2013 11:20:14 +0100 Subject: Keep all security rules in one place, support Apache 2.4 syntax --- .htaccess | 20 ++++++++++++++------ config/.htaccess | 2 -- logs/.htaccess | 2 -- program/.htaccess | 4 ---- temp/.htaccess | 2 -- 5 files changed, 14 insertions(+), 16 deletions(-) delete mode 100644 config/.htaccess delete mode 100644 logs/.htaccess delete mode 100644 program/.htaccess delete mode 100644 temp/.htaccess diff --git a/.htaccess b/.htaccess index 10af3094e..43ab5b04f 100644 --- a/.htaccess +++ b/.htaccess @@ -26,17 +26,25 @@ php_value session.gc_probability 1 RewriteEngine On RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico + # security rules -RewriteRule \.git - [F] -RewriteRule ^/?(README(.md)?|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ - [NC,F] -RewriteRule ^/?(SQL|bin) - [NC,F] +RewriteRule ^/?(\.git|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F] +RewriteRule /?(README(.md)?|composer\.json-dist|composer\.json|package\.xml)$ - [F] # deny access to all files not containing a "." (dot) -# to block access to different README, ChangeLog, etc. files -# of various skins and plugins. +# to block access to different README, Changelog, INSTALL, etc. +# files of various skins and plugins. -Deny from all + # Apache 2.4 + + Require all denied + + # Apache 2.2 + + Order Allow,Deny + Deny from all + diff --git a/config/.htaccess b/config/.htaccess deleted file mode 100644 index 8e6a345dc..000000000 --- a/config/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order allow,deny -Deny from all \ No newline at end of file diff --git a/logs/.htaccess b/logs/.htaccess deleted file mode 100644 index 8e6a345dc..000000000 --- a/logs/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order allow,deny -Deny from all \ No newline at end of file diff --git a/program/.htaccess b/program/.htaccess deleted file mode 100644 index be9e7e25a..000000000 --- a/program/.htaccess +++ /dev/null @@ -1,4 +0,0 @@ - -RewriteEngine On -RewriteRule !^(js|resources) - [F] - diff --git a/temp/.htaccess b/temp/.htaccess deleted file mode 100644 index 8e6a345dc..000000000 --- a/temp/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order allow,deny -Deny from all \ No newline at end of file -- cgit v1.2.3 From 5c7bbfcd598c89aee17096eda1188a1b4803bcf4 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 5 Nov 2013 19:07:49 +0100 Subject: Fix regression where child messages on collapsed thread weren't selected on move/delete action (#1489415) --- program/js/list.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index 4af01e53a..4ae6c0c66 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -895,7 +895,7 @@ select_children: function(uid) for (i=0; i Date: Wed, 6 Nov 2013 13:11:31 +0100 Subject: Small performance improvements, use str_replace() instead of strtr(), do not parse query if there are no params to replace, keep one instance of (potentially long) query less in memory --- program/lib/Roundcube/rcube_db.php | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/program/lib/Roundcube/rcube_db.php b/program/lib/Roundcube/rcube_db.php index aaba28172..2828f26ee 100644 --- a/program/lib/Roundcube/rcube_db.php +++ b/program/lib/Roundcube/rcube_db.php @@ -392,7 +392,7 @@ class rcube_db */ protected function _query($query, $offset, $numrows, $params) { - $query = trim($query); + $query = ltrim($query); $this->db_connect($this->dsn_select($query), true); @@ -405,27 +405,28 @@ class rcube_db $query = $this->set_limit($query, $numrows, $offset); } - $params = (array) $params; - // Because in Roundcube we mostly use queries that are // executed only once, we will not use prepared queries $pos = 0; $idx = 0; - while ($pos = strpos($query, '?', $pos)) { - if ($query[$pos+1] == '?') { // skip escaped ? - $pos += 2; - } - else { - $val = $this->quote($params[$idx++]); - unset($params[$idx-1]); - $query = substr_replace($query, $val, $pos, 1); - $pos += strlen($val); + if (count($params)) { + while ($pos = strpos($query, '?', $pos)) { + if ($query[$pos+1] == '?') { // skip escaped '?' + $pos += 2; + } + else { + $val = $this->quote($params[$idx++]); + unset($params[$idx-1]); + $query = substr_replace($query, $val, $pos, 1); + $pos += strlen($val); + } } } - // replace escaped ? back to normal - $query = rtrim(strtr($query, array('??' => '?')), ';'); + // replace escaped '?' back to normal, see self::quote() + $query = str_replace('??', '?', $query); + $query = rtrim($query, " \t\n\r\0\x0B;"); $this->debug($query); -- cgit v1.2.3