summaryrefslogtreecommitdiff
path: root/program/steps
diff options
context:
space:
mode:
Diffstat (limited to 'program/steps')
-rw-r--r--program/steps/addressbook/save.inc4
-rw-r--r--program/steps/mail/compose.inc63
-rw-r--r--program/steps/mail/func.inc53
-rw-r--r--program/steps/mail/sendmail.inc33
-rw-r--r--program/steps/settings/edit_response.inc107
-rw-r--r--program/steps/settings/func.inc22
-rw-r--r--program/steps/settings/responses.inc128
-rw-r--r--program/steps/settings/save_prefs.inc1
-rw-r--r--program/steps/utils/save_pref.inc22
-rw-r--r--program/steps/utils/spell.inc3
10 files changed, 377 insertions, 59 deletions
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 2adc53bcf..7911802b9 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -80,8 +80,8 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
// normalize the submitted date strings
if ($colprop['type'] == 'date') {
- if ($timestamp = rcube_utils::strtotime($a_record[$col])) {
- $a_record[$col] = date('Y-m-d', $timestamp);
+ if ($a_record[$col] && ($dt = rcube_utils::anytodatetime($a_record[$col]))) {
+ $a_record[$col] = $dt->format('Y-m-d');
}
else {
unset($a_record[$col]);
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index dc2452506..646d2bcd1 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -109,7 +109,8 @@ if (!is_array($COMPOSE))
$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'cancel',
'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage',
'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany',
- 'fileuploaderror', 'sendmessage');
+ 'fileuploaderror', 'sendmessage', 'savenewresponse', 'responsename', 'responsetext', 'save',
+ 'savingresponse');
$OUTPUT->set_env('compose_id', $COMPOSE['id']);
$OUTPUT->set_pagetitle(rcube_label('compose'));
@@ -852,29 +853,14 @@ function rcmail_compose_body($attrib)
// Set language list
if (!empty($CONFIG['enable_spellcheck'])) {
- $engine = $RCMAIL->config->get('spellcheck_engine','googie');
+ $engine = new rcube_spellchecker();
$dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary');
- $spellcheck_langs = (array) $RCMAIL->config->get('spellcheck_languages',
- array('da'=>'Dansk', 'de'=>'Deutsch', 'en' => 'English', 'es'=>'Español',
- 'fr'=>'Français', 'it'=>'Italiano', 'nl'=>'Nederlands', 'pl'=>'Polski',
- 'pt'=>'Português', 'ru'=>'Русский', 'fi'=>'Suomi', 'sv'=>'Svenska'));
-
- // googie works only with two-letter codes
- if ($engine == 'googie') {
- $lang = strtolower(substr($_SESSION['language'], 0, 2));
-
- $spellcheck_langs_googie = array();
- foreach ($spellcheck_langs as $key => $name)
- $spellcheck_langs_googie[strtolower(substr($key,0,2))] = $name;
- $spellcheck_langs = $spellcheck_langs_googie;
- }
- else {
- $lang = $_SESSION['language'];
+ $spellcheck_langs = $engine->languages();
+ $lang = $_SESSION['language'];
- // if not found in the list, try with two-letter code
- if (!$spellcheck_langs[$lang])
- $lang = strtolower(substr($lang, 0, 2));
- }
+ // if not found in the list, try with two-letter code
+ if (!$spellcheck_langs[$lang])
+ $lang = strtolower(substr($lang, 0, 2));
if (!$spellcheck_langs[$lang])
$lang = 'en';
@@ -1757,6 +1743,38 @@ function compose_file_drop_area($attrib)
}
+/**
+ *
+ */
+function rcmail_compose_responses_list($attrib)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'ul', 'cols' => 1);
+
+ $jsenv = array();
+ $list = new html_table($attrib);
+ foreach ($RCMAIL->get_compose_responses(true) as $response) {
+ $key = $response['key'];
+ $item = html::a(array(
+ 'href '=> '#'.urlencode($response['name']),
+ 'class' => rtrim('insertresponse ' . $attrib['itemclass']),
+ 'unselectable' => 'on',
+ 'rel' => $key,
+ ), Q($response['name']));
+
+ $jsenv[$key] = $response;
+ $list->add(array(), $item);
+ }
+
+ // set client env
+ $OUTPUT->set_env('textresponses', $jsenv);
+ $OUTPUT->add_gui_object('responseslist', $attrib['id']);
+
+ return $list->show();
+}
+
+
// register UI objects
$OUTPUT->add_handlers(array(
'composeheaders' => 'rcmail_compose_headers',
@@ -1773,6 +1791,7 @@ $OUTPUT->add_handlers(array(
'storetarget' => 'rcmail_store_target_selection',
'addressbooks' => 'rcmail_addressbook_list',
'addresslist' => 'rcmail_contacts_list',
+ 'responseslist' => 'rcmail_compose_responses_list',
));
$OUTPUT->send('compose');
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 48afecb60..78a977b82 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -97,6 +97,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
$OUTPUT->set_env('delimiter', $delimiter);
$OUTPUT->set_env('threading', $threading);
$OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD'));
+ $OUTPUT->set_env('reply_all_mode', (int) $RCMAIL->config->get('reply_all_mode'));
$OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0));
if ($RCMAIL->storage->get_capability('QUOTA')) {
$OUTPUT->set_env('quota', true);
@@ -1775,28 +1776,34 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
}
}
- $from_idx = null;
- $found_idx = null;
- $default_identity = 0; // default identity is always first on the list
+ // decode From: address
+ $from = rcube_mime::decode_address_list($MESSAGE->headers->from, null, true, $MESSAGE->headers->charset);
+ $from = array_shift($from);
+ $from['mailto'] = strtolower($from['mailto']);
+
+ $from_idx = null;
+ $found_idx = array('to' => null, 'from' => null);
+ $check_from = in_array($compose_mode, array('draft', 'edit', 'reply'));
// Select identity
foreach ($identities as $idx => $ident) {
- // use From header
- if (in_array($compose_mode, array('draft', 'edit'))) {
- if ($MESSAGE->headers->from == $ident['ident']) {
+ // use From: header when in edit/draft or reply-to-self
+ if ($check_from && $from['mailto'] == strtolower($ident['email_ascii'])) {
+ // remember first matching identity address
+ if ($found_idx['from'] === null) {
+ $found_idx['from'] = $idx;
+ }
+ // match identity name
+ if ($from['name'] && $ident['name'] && $from['name'] == $ident['name']) {
$from_idx = $idx;
break;
}
}
- // reply to yourself
- else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) {
- $from_idx = $idx;
- break;
- }
- // use replied message recipients
+ // use replied/forwarded message recipients
else if (($found = array_search(strtolower($ident['email_ascii']), $a_recipients)) !== false) {
- if ($found_idx === null) {
- $found_idx = $idx;
+ // remember first matching identity address
+ if ($found_idx['to'] === null) {
+ $found_idx['to'] = $idx;
}
// match identity name
if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
@@ -1806,22 +1813,27 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
}
}
- // If matching by name+address doesn't found any matches, get first found address (identity)
+ // If matching by name+address didn't find any matches,
+ // get first found identity (address) if any
if ($from_idx === null) {
- $from_idx = $found_idx;
+ $from_idx = $found_idx['from'] !== null ? $found_idx['from'] : $found_idx['to'];
}
// Try Return-Path
if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
+ $return_path = array_map('strtolower', (array) $return_path);
+
foreach ($identities as $idx => $ident) {
// Return-Path header contains an email address, but on some mailing list
// it can be e.g. <pear-dev-return-55250-local=domain.tld@lists.php.net>
// where local@domain.tld is the address we're looking for (#1489241)
- $ident1 = $ident['email_ascii'];
+ $ident1 = strtolower($ident['email_ascii']);
$ident2 = str_replace('@', '=', $ident1);
+ $ident1 = '<' . $ident1 . '>';
+ $ident2 = '-' . $ident2 . '@';
- foreach ((array)$return_path as $path) {
- if (stripos($path, $ident1) !== false || stripos($path, $ident2)) {
+ foreach ($return_path as $path) {
+ if ($path == $ident1 || stripos($path, $ident2)) {
$from_idx = $idx;
break 2;
}
@@ -1835,7 +1847,8 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
$selected = $plugin['selected'];
- return $identities[$selected !== null ? $selected : $default_identity];
+ // default identity is always first on the list
+ return $identities[$selected !== null ? $selected : 0];
}
// Fixes some content-type names
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index ccb8978be..52b02ecff 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -615,22 +615,39 @@ else {
}
// add stored attachments, if any
-if (is_array($COMPOSE['attachments']))
-{
+if (is_array($COMPOSE['attachments'])) {
foreach ($COMPOSE['attachments'] as $id => $attachment) {
// This hook retrieves the attachment contents from the file storage backend
$attachment = $RCMAIL->plugins->exec_hook('attachment_get', $attachment);
- $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]*/';
- $message_body = $MAIL_MIME->getHTMLBody();
- if ($isHtml && (preg_match($dispurl, $message_body) > 0)) {
- $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'" ', $message_body);
+ if ($isHtml) {
+ $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]*/';
+ $message_body = $MAIL_MIME->getHTMLBody();
+ $is_inline = preg_match($dispurl, $message_body);
+ }
+ else {
+ $is_inline = false;
+ }
+
+ // inline image
+ if ($is_inline) {
+ // Mail_Mime does not support many inline attachments with the same name (#1489406)
+ // we'll generate cid: urls here to workaround this
+ $cid = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true));
+ if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $from, $matches)) {
+ $cid .= $matches[1];
+ } else {
+ $cid .= '@localhost';
+ }
+
+ $message_body = preg_replace($dispurl, ' src="cid:' . $cid . '" ', $message_body);
+
$MAIL_MIME->setHTMLBody($message_body);
if ($attachment['data'])
- $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false);
+ $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false, $cid);
else
- $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true);
+ $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true, $cid);
}
else {
$ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914
diff --git a/program/steps/settings/edit_response.inc b/program/steps/settings/edit_response.inc
new file mode 100644
index 000000000..49856775a
--- /dev/null
+++ b/program/steps/settings/edit_response.inc
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_response.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Show edit form for a canned response record or to add a new one |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$responses = $RCMAIL->get_compose_responses();
+
+// edit-response
+if (($key = get_input_value('_key', RCUBE_INPUT_GPC))) {
+ foreach ($responses as $i => $response) {
+ if ($response['key'] == $key) {
+ $RESPONSE_RECORD = $response;
+ $RESPONSE_RECORD['index'] = $i;
+ break;
+ }
+ }
+}
+
+// save response
+if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ foreach ($responses as $i => $resp) {
+ if ($RESPONSE_RECORD && $RESPONSE_RECORD['index'] === $i)
+ continue;
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ if ($RESPONSE_RECORD && $responses[$RESPONSE_RECORD['index']]) {
+ $responses[$RESPONSE_RECORD['index']] = $response;
+ }
+ else {
+ $responses[] = $response;
+ }
+
+ $responses = array_filter($responses, function($item){ return empty($item['static']); });
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => array_values($responses)))) {
+ $RCMAIL->output->show_message('successfullysaved', 'confirmation');
+ $RCMAIL->output->command('parent.update_response_row', $response, $key);
+ $RCMAIL->overwrite_action('edit-response');
+ $RESPONSE_RECORD = $response;
+ }
+ }
+ else {
+ $RCMAIL->output->show_message('formincomplete', 'error');
+ }
+}
+
+
+function rcube_response_form($attrib)
+{
+ global $RCMAIL, $OUTPUT, $RESPONSE_RECORD;
+
+ // Set form tags and hidden fields
+ $disabled = !empty($RESPONSE_RECORD['static']);
+ $key = $RESPONSE_RECORD['key'];
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-response', $key, array('name' => '_key', 'value' => $key));
+ unset($attrib['form'], $attrib['id']);
+
+ // return the complete edit form as table
+ $out = "$form_start\n";
+
+ $table = new html_table(array('cols' => 2));
+ $label = rcube_label('responsename');
+
+ $table->add('title', html::label('ffname', Q(rcube_label('responsename'))));
+ $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], array('id' => 'ffname', 'size' => $attrib['size'], 'disabled' => $disabled), 'text'));
+
+ $table->add('title', html::label('fftext', Q(rcube_label('responsetext'))));
+ $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows'], 'disabled' => $disabled), 'textarea'));
+
+ $out .= $table->show($attrib);
+ $out .= $form_end;
+
+ return $out;
+}
+
+$OUTPUT->set_env('readonly', !empty($RESPONSE_RECORD['static']));
+$OUTPUT->add_handler('responseform', 'rcube_response_form');
+$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-response' ? 'savenewresponse' : 'editresponse')));
+
+$OUTPUT->send('responseedit');
+
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index af278e5fa..c922aca08 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -869,6 +869,24 @@ function rcmail_user_prefs($current = null)
$select_default_font_size->show($RCMAIL->config->get('default_font_size', 1))
);
}
+
+ if (!isset($no_override['reply_all_mode'])) {
+ if (!$current) {
+ continue 2;
+ }
+
+ $field_id = 'rcmfd_reply_all_mode';
+ $select = new html_select(array('name' => '_reply_all_mode', 'id' => $field_id));
+
+ $select->add(rcube_label('replyalldefault'), 0);
+ $select->add(rcube_label('replyalllist'), 1);
+
+ $blocks['main']['options']['reply_all_mode'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('replyallmode'))),
+ 'content' => $select->show(intval($config['reply_all_mode'])),
+ );
+ }
+
break;
// Addressbook config
@@ -1260,6 +1278,7 @@ function rcmail_settings_tabs($attrib)
array('command' => 'preferences', 'type' => 'link', 'label' => 'preferences', 'title' => 'editpreferences'),
array('command' => 'folders', 'type' => 'link', 'label' => 'folders', 'title' => 'managefolders'),
array('command' => 'identities', 'type' => 'link', 'label' => 'identities', 'title' => 'manageidentities'),
+ array('command' => 'responses', 'type' => 'link', 'label' => 'responses', 'title' => 'editresponses'),
);
// get all identites from DB and define list of cols to be displayed
@@ -1321,4 +1340,7 @@ $RCMAIL->register_action_map(array(
'purge' => 'folders.inc',
'folder-size' => 'folders.inc',
'add-identity' => 'edit_identity.inc',
+ 'add-response' => 'edit_response.inc',
+ 'save-response' => 'edit_response.inc',
+ 'delete-response' => 'responses.inc',
));
diff --git a/program/steps/settings/responses.inc b/program/steps/settings/responses.inc
new file mode 100644
index 000000000..cfc4148c3
--- /dev/null
+++ b/program/steps/settings/responses.inc
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/responses.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Manage and save canned response texts |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+if (!empty($_POST['_insert'])) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $resp) {
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ $responses[] = $response;
+
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => $responses))) {
+ $RCMAIL->output->command('add_response_item', $response);
+ $RCMAIL->output->command('display_message', rcube_label('successfullysaved'), 'confirmation');
+ }
+ else {
+ $RCMAIL->output->command('display_message', rcube_label('errorsaving'), 'error');
+ }
+ }
+
+ // send response
+ $RCMAIL->output->send();
+}
+
+
+if ($RCMAIL->action == 'delete-response') {
+ if ($key = get_input_value('_key', RCUBE_INPUT_GPC)) {
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $i => $response) {
+ if (empty($response['key']))
+ $response['key'] = substr(md5($response['name']), 0, 16);
+ if ($response['key'] == $key) {
+ unset($responses[$i]);
+ $deleted = $RCMAIL->user->save_prefs(array('compose_responses' => $responses));
+ break;
+ }
+ }
+ }
+
+ if ($deleted) {
+ $RCMAIL->output->command('display_message', rcube_label('deletedsuccessfully'), 'confirmation');
+ $RCMAIL->output->command('remove_response', $key);
+ }
+
+ if ($RCMAIL->output->ajax_call) {
+ $RCMAIL->output->send();
+ }
+}
+
+
+$OUTPUT->set_pagetitle(rcube_label('responses'));
+$OUTPUT->include_script('list.js');
+
+
+/**
+ *
+ */
+function rcmail_responses_list($attrib)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'table', 'cols' => 1);
+
+ $plugin = $RCMAIL->plugins->exec_hook('responses_list', array(
+ 'list' => $RCMAIL->get_compose_responses(true),
+ 'cols' => array('name')
+ ));
+
+ $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'key');
+
+ // set client env
+ $OUTPUT->add_gui_object('responseslist', $attrib['id']);
+ $OUTPUT->set_env('readonly_responses', array_values(array_map(function($rec){ return $rec['key']; },
+ array_filter($plugin['list'], function($item){ return !empty($item['static']); }))));
+
+ return $out;
+}
+
+
+// similar function as /steps/addressbook/func.inc::rcmail_contact_frame()
+function rcmail_response_frame($attrib)
+{
+ global $OUTPUT;
+
+ if (!$attrib['id']) {
+ $attrib['id'] = 'rcmResponseFrame';
+ }
+
+ $OUTPUT->set_env('contentframe', $attrib['id']);
+ return $OUTPUT->frame($attrib, true);
+}
+
+$OUTPUT->add_handlers(array(
+ 'responseframe' => 'rcmail_response_frame',
+ 'responseslist' => 'rcmail_responses_list',
+));
+$OUTPUT->add_label('deleteresponseconfirm');
+
+$OUTPUT->send('responses');
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index 717c7ad8c..bcd05bb85 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -90,6 +90,7 @@ switch ($CURR_SECTION)
'strip_existing_sig' => isset($_POST['_strip_existing_sig']),
'default_font' => get_input_value('_default_font', RCUBE_INPUT_POST),
'default_font_size' => get_input_value('_default_font_size', RCUBE_INPUT_POST),
+ 'reply_all_mode' => intval($_POST['_reply_all_mode']),
'forward_attachment' => !empty($_POST['_forward_attachment']),
);
diff --git a/program/steps/utils/save_pref.inc b/program/steps/utils/save_pref.inc
index 7def8733d..7c30be71b 100644
--- a/program/steps/utils/save_pref.inc
+++ b/program/steps/utils/save_pref.inc
@@ -5,7 +5,7 @@
| program/steps/utils/save_pref.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2010, The Roundcube Dev Team |
+ | Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -19,16 +19,26 @@
+-----------------------------------------------------------------------+
*/
-$name = get_input_value('_name', RCUBE_INPUT_POST);
-$value = get_input_value('_value', RCUBE_INPUT_POST);
+$name = get_input_value('_name', RCUBE_INPUT_POST);
+$value = get_input_value('_value', RCUBE_INPUT_POST);
+$sessname = get_input_value('_session', RCUBE_INPUT_POST);
+
+// Whitelisted preferences and session variables, others
+// can be added by plugins
$whitelist = array(
'preview_pane',
'list_cols',
'collapsed_folders',
'collapsed_abooks',
);
+$whitelist_sess = array(
+ 'list_attrib/columns',
+);
+
+$whitelist = array_merge($whitelist, $RCMAIL->plugins->allowed_prefs);
+$whitelist_sess = array_merge($whitelist_sess, $RCMAIL->plugins->allowed_session_prefs);
-if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) {
+if (!in_array($name, $whitelist) || ($sessname && !in_array($sessname, $whitelist_sess))) {
raise_error(array('code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => sprintf("Hack attempt detected (user: %s)", $RCMAIL->get_user_name())),
@@ -42,7 +52,7 @@ if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs)))
$RCMAIL->user->save_prefs(array($name => $value));
// update also session if requested
-if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
+if ($sessname) {
// Support multidimensional arrays...
$vars = explode('/', $sessname);
@@ -57,5 +67,3 @@ if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
$OUTPUT->reset();
$OUTPUT->send();
-
-
diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc
index 1c68e8328..595cfd6f2 100644
--- a/program/steps/utils/spell.inc
+++ b/program/steps/utils/spell.inc
@@ -47,6 +47,9 @@ if ($err = $spellchecker->error()) {
'file' => __FILE__, 'line' => __LINE__,
'message' => "Spell check engine error: " . trim($err)),
true, false);
+
+ header("HTTP/1.0 500 Internal Server Error");
+ exit;
}
// set response length