X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=src%2Fcompose.php;h=b5bf404d5ee115578854299544293f0593384821;hp=89dc5603c4f626d6d01683ef3f227ad68d0788d4;hb=bf95f4e0adc4e2422e16a0659a9843d4b0f57dec;hpb=5df2efa257f7aa8ddcfa44ed517a8cef8c26b118 diff --git a/src/compose.php b/src/compose.php index 89dc5603..b5bf404d 100644 --- a/src/compose.php +++ b/src/compose.php @@ -10,7 +10,7 @@ * - Send mail * - Save As Draft * - * @copyright 1999-2012 The SquirrelMail Project Team + * @copyright 1999-2019 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail @@ -41,6 +41,7 @@ require_once(SM_PATH . 'class/deliver/Deliver.class.php'); require_once(SM_PATH . 'functions/addressbook.php'); require_once(SM_PATH . 'functions/forms.php'); require_once(SM_PATH . 'functions/identity.php'); +global $imap_stream_options; // in case not defined in config /* --------------------- Get globals ------------------------------------- */ @@ -54,7 +55,8 @@ sqgetGlobalVar('compose_messages', $compose_messages, SQ_SESSION); // compose_messages only useful in SESSION when a forward-as-attachment // has been preconstructed for us and passed in via that mechanism; once // we have it, we can clear it from the SESSION -sqsession_unregister('compose_messages'); +// -- No, this is useful in other scenarios, too -- removing: +// sqsession_unregister('compose_messages'); // Turn on delayed error handling in case we wind up redirecting below $oErrorHandler->setDelayedErrors(true); @@ -72,6 +74,7 @@ if (isset($send) && $send) { } sqgetGlobalVar('session',$session, $SQ_GLOBAL); sqgetGlobalVar('mailbox',$mailbox, $SQ_GLOBAL); +sqgetGlobalVar('identity',$orig_identity, $SQ_GLOBAL); if(!sqgetGlobalVar('identity',$identity, $SQ_GLOBAL)) { $identity=0; } @@ -172,8 +175,12 @@ function replyAllString($header) { /** * 1) Remove the addresses we'll be sending the message 'to' */ - if (isset($header->reply_to)) { + if (isset($header->reply_to) && is_array($header->reply_to) && count($header->reply_to)) { $excl_ar = $header->getAddr_a('reply_to'); + } else if (is_object($header->reply_to)) { /* unneccesarry, just for failsafe purpose */ + $excl_ar = $header->getAddr_a('reply_to'); + } else { + $excl_ar = $header->getAddr_a('from'); } /** * 2) Remove our identities from the CC list (they still can be in the @@ -244,6 +251,7 @@ function getReplyCitation($orig_from, $orig_date) { $full_reply_citation = sprintf(_("%s wrote:"),$sOrig_from); break; case 'quote_who': + // TODO: the words "quote" and "who" are translated in 1.4.x so why not here? This isn't a real HTML tag... $start = ''; $full_reply_citation = $start . $sOrig_from . $end; @@ -403,8 +411,25 @@ if (!empty($compose_messages[$session])) { // should never directly manipulate an object like this if (!empty($attachments)) { $attachments = unserialize(urldecode($attachments)); - if (!empty($attachments) && is_array($attachments)) - $composeMessage->entities = $attachments; + if (!empty($attachments) && is_array($attachments)) { + // sanitize the "att_local_name" since it is user-supplied and used to access the file system + // it must be alpha-numeric and 32 characters long (see the use of GenerateRandomString() below) + foreach ($attachments as $i => $attachment) { + if (empty($attachment->att_local_name) || strlen($attachment->att_local_name) !== 32) { + unset($attachments[$i]); + continue; + } + // probably marginal difference between (ctype_alnum + function_exists) and preg_match + if (function_exists('ctype_alnum')) { + if (!ctype_alnum($attachment->att_local_name)) + unset($attachments[$i]); + } + else if (preg_match('/[^0-9a-zA-Z]/', $attachment->att_local_name)) + unset($attachments[$i]); + } + if (!empty($attachments)) + $composeMessage->entities = $attachments; + } } if (empty($mailbox)) { @@ -415,7 +440,7 @@ if ($draft) { // validate security token // - sm_validate_security_token($submitted_token, 3600, TRUE); + sm_validate_security_token($submitted_token, -1, TRUE); /* * Set $default_charset to correspond with the user's selection @@ -429,7 +454,7 @@ if ($draft) { $draft_message = _("Draft Email Saved"); /* If this is a resumed draft, then delete the original */ if(isset($delete_draft)) { - $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false); + $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false, $imap_stream_options); sqimap_mailbox_select($imap_stream, $draft_folder); // force bypass_trash=true because message should be saved when deliverMessage() returns true. // in current implementation of sqimap_msgs_list_flag() single message id can @@ -474,7 +499,7 @@ if ($send) { // validate security token // - sm_validate_security_token($submitted_token, 3600, TRUE); + sm_validate_security_token($submitted_token, -1, TRUE); if (isset($_FILES['attachfile']) && $_FILES['attachfile']['tmp_name'] && @@ -542,7 +567,7 @@ if ($send) { /* if it is resumed draft, delete draft message */ if ( isset($delete_draft)) { - $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false); + $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false, $imap_stream_options); sqimap_mailbox_select($imap_stream, $draft_folder); // bypass_trash=true because message should be saved when deliverMessage() returns true. // in current implementation of sqimap_msgs_list_flag() single message id can @@ -571,8 +596,14 @@ if ($send) { exit(); } else { if ( !isset($pageheader_sent) || !$pageheader_sent ) { - header("Location: $location/right_main.php?mailbox=$urlMailbox". - "&startMessage=$startMessage&mail_sent=$mail_sent"); + global $return_to_message_after_reply; + if (($action === 'reply' || $action === 'reply_all' || $action === 'forward' || $action === 'forward_as_attachment') + && $return_to_message_after_reply && $passed_id) + header("Location: $location/read_body.php?passed_id=$passed_id&mailbox=$urlMailbox". + "&startMessage=$startMessage&mail_sent=$mail_sent"); + else + header("Location: $location/right_main.php?mailbox=$urlMailbox". + "&startMessage=$startMessage&mail_sent=$mail_sent"); } else { //FIXME: DON'T ECHO HTML FROM CORE! echo '

$what, 'offset' => $startMessage),array()); - switch($action) { - case 'reply': - case 'reply_all': - // check if we are allowed to set the \\Answered flag - if (in_array('\\answered',$aMailbox['PERMANENTFLAGS'], true)) { - $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false); - if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) { - /** - * Only update the cached headers if the header is - * cached. - */ - if (isset($aMailbox['MSG_HEADERS'][$passed_id])) { - $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS']; + // select errors here could be due to a draft reply being sent + // after the original message's mailbox is moved or deleted + $aMailbox = sqm_api_mailbox_select($imap_stream, $iAccount, $mailbox,array('setindex' => $what, 'offset' => $startMessage),array(), false); + // a non-empty return from above means we can proceed + if (!empty($aMailbox)) { + switch($action) { + case 'reply': + case 'reply_all': + // check if we are allowed to set the \\Answered flag + if (in_array('\\answered',$aMailbox['PERMANENTFLAGS'], true)) { + $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false); + if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) { + /** + * Only update the cached headers if the header is + * cached. + */ + if (isset($aMailbox['MSG_HEADERS'][$passed_id])) { + $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS']; + } } } - } - break; - case 'forward': - case 'forward_as_attachment': - // check if we are allowed to set the $Forwarded flag (RFC 4550 paragraph 2.8) - if (in_array('$forwarded',$aMailbox['PERMANENTFLAGS'], true) || - in_array('\\*',$aMailbox['PERMANENTFLAGS'])) { - - // when forwarding as an attachment from the message - // list, passed_id is not used, need to get UID(s) - // from the query string - // - if (empty($passed_id) && !empty($fwduid)) - $ids = explode('_', $fwduid); - else - $ids = array($passed_id); - - $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, $ids, '$Forwarded', true, false); - - foreach ($ids as $id) { - if (isset($aUpdatedMsgs[$id]['FLAGS'])) { - if (isset($aMailbox['MSG_HEADERS'][$id])) { - $aMailbox['MSG_HEADERS'][$id]['FLAGS'] = $aMsg['FLAGS']; + break; + case 'forward': + case 'forward_as_attachment': + // check if we are allowed to set the $Forwarded flag (RFC 4550 paragraph 2.8) + if (in_array('$forwarded',$aMailbox['PERMANENTFLAGS'], true) || + in_array('\\*',$aMailbox['PERMANENTFLAGS'])) { + + // when forwarding as an attachment from the message + // list, passed_id is not used, need to get UID(s) + // from the query string + // + if (empty($passed_id) && !empty($fwduid)) + $ids = explode('_', $fwduid); + else + $ids = array($passed_id); + + $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, $ids, '$Forwarded', true, false); + + foreach ($ids as $id) { + if (isset($aUpdatedMsgs[$id]['FLAGS'])) { + if (isset($aMailbox['MSG_HEADERS'][$id])) { + $aMailbox['MSG_HEADERS'][$id]['FLAGS'] = $aMsg['FLAGS']; + } } } } + break; } - break; - } - /** - * Write mailbox with updated seen flag information back to cache. - */ - if(isset($aUpdatedMsgs[$passed_id])) { - $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox; - sqsession_register($mailbox_cache,'mailbox_cache'); + /** + * Write mailbox with updated seen flag information back to cache. + */ + if(isset($aUpdatedMsgs[$passed_id])) { + $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox; + sqsession_register($mailbox_cache,'mailbox_cache'); + } } - } @@ -1923,6 +2010,9 @@ function deliverMessage(&$composeMessage, $draft=false) { // final cleanup // $composeMessage->purgeAttachments(); +//TODO: completely unclear if should be using $compose_session instead of $session below + unset($compose_messages[$session]); + sqsession_register($compose_messages,'compose_messages'); sqimap_logout($imap_stream); }