X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=functions%2Fmailbox_display.php;h=41a277a9c91cbbe016da22236cbd1bb2609aed10;hp=cf953a7dc0570c7c9a8c29c60236230784cd3763;hb=d72549cb90b0473f1d7a99e796ede80dac1b1ec3;hpb=0e525861899c6a4d93c424a5a19c249841889cd9 diff --git a/functions/mailbox_display.php b/functions/mailbox_display.php index cf953a7d..41a277a9 100644 --- a/functions/mailbox_display.php +++ b/functions/mailbox_display.php @@ -6,7 +6,7 @@ * This contains functions that display mailbox information, such as the * table row that has sender, date, subject, etc... * - * @copyright © 1999-2007 The SquirrelMail Project Team + * @copyright 1999-2013 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail @@ -554,11 +554,11 @@ function prepareMessageList(&$aMailbox, $aProps) { $sMailbox = (isset($aAddr[SQM_ADDR_MAILBOX])) ? $aAddr[SQM_ADDR_MAILBOX] : ''; $sHost = (isset($aAddr[SQM_ADDR_HOST])) ? $aAddr[SQM_ADDR_HOST] : ''; if ($sPersonal) { - $title .= htmlspecialchars($sMailbox.'@'.$sHost).', '; + $title .= sm_encode_html_special_chars($sMailbox.'@'.$sHost).', '; } else { // if $value gets truncated we need to add the addresses with no // personal name as well - $title_maybe .= htmlspecialchars($sMailbox.'@'.$sHost).', '; + $title_maybe .= sm_encode_html_special_chars($sMailbox.'@'.$sHost).', '; } } if ($title) { @@ -566,10 +566,10 @@ function prepareMessageList(&$aMailbox, $aProps) { } $sTmp = decodeHeader($sTmp); if (isset($aColumnDesc[$k]['truncate']) && $aColumnDesc[$k]['truncate']) { - $sTrunc = truncateWithEntities($sTmp, $aColumnDesc[$k]['truncate']); + $sTrunc = sm_truncate_string($sTmp, $aColumnDesc[$k]['truncate'], '...', TRUE); if ($sTrunc != $sTmp) { if (!$title) { - $title = htmlspecialchars($sTmp); + $title = $sTmp; } else if ($title_maybe) { $title = $title .', '.$title_maybe; $title = substr($title,0,-2); // strip ', '; @@ -578,7 +578,7 @@ function prepareMessageList(&$aMailbox, $aProps) { $sTmp = $sTrunc; } } - $value = ($sTmp) ? $sTmp : $sUnknown; + $value = ($sTmp) ? (substr($sTmp, 0, 6) == '"' && substr($sTmp, -6) == '"' ? substr(substr($sTmp, 0, -6), 6) : $sTmp) : $sUnknown; break; case SQM_COL_SUBJ: // subject is mime encoded, decode it. @@ -591,7 +591,7 @@ function prepareMessageList(&$aMailbox, $aProps) { $iIndent = (isset($aIndentArray[$aId[$i]])) ? $aIndentArray[$aId[$i]] : 0; // FIXME: don't break 8bit symbols and html entities during truncation if (isset($aColumnDesc[$k]['truncate']) && $aColumnDesc[$k]['truncate']) { - $sTmp = truncateWithEntities($value, $aColumnDesc[$k]['truncate']-$iIndent); + $sTmp = sm_truncate_string($value, $aColumnDesc[$k]['truncate']-$iIndent, '...', TRUE); // drop any double spaces since these will be displayed in the title $title = ($sTmp != $value) ? preg_replace('/\s{2,}/', ' ', $value) : ''; $value = $sTmp; @@ -618,23 +618,27 @@ function prepareMessageList(&$aMailbox, $aProps) { break; case SQM_COL_DATE: case SQM_COL_INT_DATE: - $value = getDateString(getTimeStamp(explode(' ',trim($value)))); + $value = getTimeStamp(explode(' ',trim($value))); + $title = getDateString($value, TRUE); + $value = getDateString($value); break; case SQM_COL_FLAGS: $aFlagColumn = array('seen' => false, 'deleted'=>false, 'answered'=>false, + 'forwarded'=>false, 'flagged' => false, 'draft' => false); if(!is_array($value)) $value = array(); - foreach ($value as $sFlag => $value) { + foreach ($value as $sFlag => $v) { switch ($sFlag) { - case '\\seen' : $aFlagColumn['seen'] = true; break; - case '\\deleted' : $aFlagColumn['deleted'] = true; break; - case '\\answered': $aFlagColumn['answered'] = true; break; - case '\\flagged' : $aFlagColumn['flagged'] = true; break; - case '\\draft' : $aFlagColumn['draft'] = true; break; + case '\\seen' : $aFlagColumn['seen'] = true; break; + case '\\deleted' : $aFlagColumn['deleted'] = true; break; + case '\\answered': $aFlagColumn['answered'] = true; break; + case '$forwarded': $aFlagColumn['forwarded'] = true; break; + case '\\flagged' : $aFlagColumn['flagged'] = true; break; + case '\\draft' : $aFlagColumn['draft'] = true; break; default: break; } } @@ -973,7 +977,7 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { $source_url = $php_self; } - $baseurl = $source_url.'?mailbox=' . urlencode($aMailbox['NAME']) .'&account='.$aMailbox['ACCOUNT']; + $baseurl = $source_url.'?mailbox=' . urlencode($aMailbox['NAME']) .'&account='.$aMailbox['ACCOUNT'] . (strpos($source_url, 'src/search.php') ? '&smtoken=' . sm_generate_security_token() : ''); $where = urlencode($aMailbox['SEARCH'][$iSetIndx][0]); $what = urlencode($aMailbox['SEARCH'][$iSetIndx][1]); $baseurl .= '&where=' . $where . '&what=' . $what; @@ -1002,8 +1006,8 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { /* future admin control over displayable buttons */ $aAdminControl = array( - 'markUnflagged' => 1, 'markFlagged' => 1, + 'markUnflagged' => 1, 'markRead' => 1, 'markUnread' => 1, 'forward' => 1, @@ -1018,8 +1022,8 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { /* user prefs control */ $aUserControl = array ( - 'markUnflagged' => $show_flag_buttons, 'markFlagged' => $show_flag_buttons, + 'markUnflagged' => $show_flag_buttons, 'markRead' => 1, 'markUnread' => 1, 'forward' => 1, @@ -1039,7 +1043,7 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { $trash_folder) ? true : false; // $showUndelete = (!$aMailbox['AUTO_EXPUNGE'] && $aMailbox['RIGHTS'] != 'READ-ONLY' && - in_array('\\deleted',$aMailbox['PERMANENTFLAGS'], true) && !$trash_folder) ? true : false; + in_array('\\deleted',$aMailbox['PERMANENTFLAGS'], true) /* trash folder unrelated methinks: && !$trash_folder*/) ? true : false; $showMove = ($aMailbox['RIGHTS'] != 'READ-ONLY') ? true : false; $showExpunge = (!$aMailbox['AUTO_EXPUNGE'] && $aMailbox['RIGHTS'] != 'READ-ONLY' && in_array('\\deleted',$aMailbox['PERMANENTFLAGS'], true)) ? true : false; @@ -1060,17 +1064,37 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { ); /* Button strings */ $aButtonStrings = array( - 'markUnflagged' => _("Unflag"), - 'markFlagged' => _("Flag"), - 'markRead' => _("Read"), - 'markUnread' => _("Unread"), - 'forward' => _("Forward"), - 'delete' => _("Delete"), - 'undeleteButton' => _("Undelete"), - 'bypass_trash' => _("Bypass Trash"), - 'expungeButton' => _("Expunge"), - 'moveButton' => _("Move"), - 'copyButton' => _("Copy") + 'markFlagged' => _("Flag"), + 'markUnflagged' => _("Unflag"), + 'markRead' => _("Read"), + 'markUnread' => _("Unread"), + 'forward' => _("Forward"), + 'delete' => _("Delete"), + 'undeleteButton' => _("Undelete"), + 'bypass_trash' => _("Bypass Trash"), + 'expungeButton' => _("Expunge"), + 'moveButton' => _("Move"), + 'copyButton' => _("Copy") + ); + /* Button access keys */ + global $accesskey_mailbox_flag, $accesskey_mailbox_unflag, + $accesskey_mailbox_read, $accesskey_mailbox_unread, + $accesskey_mailbox_forward, $accesskey_mailbox_delete, + $accesskey_mailbox_undelete, $accesskey_mailbox_bypass_trash, + $accesskey_mailbox_expunge, $accesskey_mailbox_move, + $accesskey_mailbox_copy, $accesskey_mailbox_move_to; + $aButtonAccessKeys = array( + 'markFlagged' => $accesskey_mailbox_flag, + 'markUnflagged' => $accesskey_mailbox_unflag, + 'markRead' => $accesskey_mailbox_read, + 'markUnread' => $accesskey_mailbox_unread, + 'forward' => $accesskey_mailbox_forward, + 'delete' => $accesskey_mailbox_delete, + 'undeleteButton' => $accesskey_mailbox_undelete, + 'bypass_trash' => $accesskey_mailbox_bypass_trash, + 'expungeButton' => $accesskey_mailbox_expunge, + 'moveButton' => $accesskey_mailbox_move, + 'copyButton' => $accesskey_mailbox_copy, ); @@ -1082,8 +1106,8 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { foreach($aAdminControl as $k => $v) { if ($v & $aUserControl[$k] & $aImapControl[$k]) { switch ($k) { - case 'markUnflagged': case 'markFlagged': + case 'markUnflagged': case 'markRead': case 'markUnread': case 'delete': @@ -1091,23 +1115,24 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { case 'expungeButton': case 'forward': $aFormElements[$k] - = array('value' => $aButtonStrings[$k], 'type' => 'submit'); + = array('value' => $aButtonStrings[$k], 'type' => 'submit', 'accesskey' => (isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE')); break; case 'bypass_trash': $aFormElements[$k] - = array('value' => $aButtonStrings[$k], 'type' => 'checkbox'); + = array('value' => $aButtonStrings[$k], 'type' => 'checkbox', 'accesskey' => (isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE')); break; case 'moveButton': case 'copyButton': $aFormElements['targetMailbox'] = array('options_list' => sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox)), 0, $boxes), - 'type' => 'select'); + 'type' => 'select', + 'accesskey' => $accesskey_mailbox_move_to); $aFormElements['mailbox'] = array('value' => $aMailbox['NAME'], 'type' => 'hidden'); $aFormElements['startMessage'] = array('value' => $aMailbox['PAGEOFFSET'], 'type' => 'hidden'); $aFormElements[$k] - = array('value' => $aButtonStrings[$k], 'type' => 'submit'); + = array('value' => $aButtonStrings[$k], 'type' => 'submit', 'accesskey' => (isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE')); break; } } @@ -1230,70 +1255,6 @@ function showMessagesForMailbox($imapConnection, &$aMailbox,$aProps, &$iError) { } -/** - * Truncates a string and take care of html encoded characters - * - * @param string $s string to truncate - * @param int $iTrimAt Trim at nn characters - * @return string Trimmed string - */ -function truncateWithEntities($s, $iTrimAt) { - global $languages, $squirrelmail_language; - - $ent_strlen = strlen($s); - if (($iTrimAt <= 0) || ($ent_strlen <= $iTrimAt)) - return $s; - - if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && - function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_strimwidth')) { - return call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_strimwidth', $s, $iTrimAt); - } else { - /* - * see if this is entities-encoded string - * If so, Iterate through the whole string, find out - * the real number of characters, and if more - * than $iTrimAt, substr with an updated trim value. - */ - $trim_val = $iTrimAt; - $ent_offset = 0; - $ent_loc = 0; - while ( $ent_loc < $trim_val && (($ent_loc = strpos($s, '&', $ent_offset)) !== false) && - (($ent_loc_end = strpos($s, ';', $ent_loc+3)) !== false) ) { - $trim_val += ($ent_loc_end-$ent_loc); - $ent_offset = $ent_loc_end+1; - } - - if (($trim_val > $iTrimAt) && ($ent_strlen > $trim_val) && (strpos($s,';',$trim_val) < ($trim_val + 6))) { - $i = strpos($s,';',$trim_val); - if ($i !== false) { - $trim_val = strpos($s,';',$trim_val)+1; - } - } - // only print '...' when we're actually dropping part of the subject - if ($ent_strlen <= $trim_val) - return $s; - } - return substr_replace($s, '...', $trim_val); -} - - -/** - * This should go in imap_mailbox.php - * @param string $mailbox - */ -function handleAsSent($mailbox) { - global $handleAsSent_result; - - /* First check if this is the sent or draft folder. */ - $handleAsSent_result = isSentMailbox($mailbox) || isDraftMailbox($mailbox); - - /* Then check the result of the handleAsSent hook. */ - do_hook('check_handleAsSent_result', $mailbox); - - /* And return the result. */ - return $handleAsSent_result; -} - /** * Process messages list form and handle the cache gracefully. If $sButton and * $aUid are provided as argument then you can fake a message list submit and @@ -1334,6 +1295,16 @@ function handleMessageListForm($imapConnection, &$aMailbox, $sButton='', /* retrieve the check boxes */ $aUid = (isset($msg) && is_array($msg)) ? array_values($msg) : $aUid; if (count($aUid) && $sButton != 'expunge') { + + // don't do anything to any messages until we have done security check + // FIXME: not sure this code really belongs here, but there's nowhere else to put it with this architecture + sqgetGlobalVar('smtoken', $submitted_token, SQ_FORM, ''); + sm_validate_security_token($submitted_token, -1, TRUE); + + // make sure message UIDs are sanitized (BIGINT) + foreach ($aUid as $i => $uid) + $aUid[$i] = (preg_match('/^[0-9]+$/', $uid) ? $uid : '0'); + $aUpdatedMsgs = false; $bExpunge = false; switch ($sButton) { @@ -1376,12 +1347,14 @@ function handleMessageListForm($imapConnection, &$aMailbox, $sButton='', if (count($aMsgHeaders)) { $composesession = attachSelectedMessages($imapConnection,$aMsgHeaders); // dirty hack, add info to $aMailbox - $aMailbox['FORWARD_SESSION'] = $composesession; + $aMailbox['FORWARD_SESSION']['SESSION_NUMBER'] = $composesession; + $aMailbox['FORWARD_SESSION']['UIDS'] = $aUid; } break; default: // Hook for plugin buttons - do_hook('mailbox_display_button_action', $aUid); + $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], &$aUid); + do_hook('mailbox_display_button_action', $temp); break; } /** @@ -1409,6 +1382,7 @@ function handleMessageListForm($imapConnection, &$aMailbox, $sButton='', $message = $aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT']; $message->is_seen = false; $message->is_answered = false; + $message->is_forwarded = false; $message->is_deleted = false; $message->is_flagged = false; $message->is_mdnsent = false; @@ -1417,6 +1391,8 @@ function handleMessageListForm($imapConnection, &$aMailbox, $sButton='', $message->is_seen = true; else if (strtolower($flag) == '\\answered' && $value) $message->is_answered = true; + else if (strtolower($flag) == '$forwarded' && $value) + $message->is_forwarded = true; else if (strtolower($flag) == '\\deleted' && $value) $message->is_deleted = true; else if (strtolower($flag) == '\\flagged' && $value) @@ -1490,7 +1466,15 @@ function handleMessageListForm($imapConnection, &$aMailbox, $sButton='', sqimap_run_command($imapConnection,'CLOSE',false,$result,$message); $aMailbox = sqm_api_mailbox_select($imapConnection,$iAccount, $aMailbox['NAME'],array(),array()); } else { - if ($sButton) { + // this is the same hook as above, but here it is called in the + // context of not having had any messages selected and if any + // plugin handles the situation, it should return TRUE so we + // know this was not an erroneous user action + // + global $null; + $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], $null); + if (!boolean_hook_function('mailbox_display_button_action', $temp, 1) + && $sButton) { $sError = _("No messages were selected."); } } @@ -1549,8 +1533,18 @@ function attachSelectedMessages($imapConnection,$aMsgHeaders) { fwrite ($fp, $body); fclose($fp); - $composeMessage->initAttachment('message/rfc822',$subject.'.msg', - $filename); + $composeMessage->initAttachment('message/rfc822', $subject . '.eml', $filename); + + // create subject for new message + // + $subject = decodeHeader($subject,false,false,true); + $subject = str_replace('"', "'", $subject); + $subject = trim($subject); + if (substr(strtolower($subject), 0, 4) != 'fwd:') { + $subject = 'Fwd: ' . $subject; + } + $composeMessage->rfc822_header->subject = $subject; + } }