From cb2bc809ef29f349d38c89e202d821e67bb4c947 Mon Sep 17 00:00:00 2001 From: thomascube <thomas@roundcube.net> Date: Tue, 21 Sep 2010 14:47:55 -0400 Subject: [PATCH] Fix db_mode check in insert_id() --- program/steps/mail/sendmail.inc | 169 ++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 102 insertions(+), 67 deletions(-) diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index 13210be..3902b9a 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -5,7 +5,7 @@ | program/steps/mail/sendmail.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2010, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -29,11 +29,11 @@ /****** checks ********/ if (!isset($_SESSION['compose']['id'])) { - raise_error(array('code' => 500, 'type' => 'smtp', + raise_error(array('code' => 500, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Invalid compose ID"), true, false); - $OUTPUT->show_message("An internal error occured. Please try again.", 'error'); + $OUTPUT->show_message('internalerror', 'error'); $OUTPUT->send('iframe'); } @@ -95,18 +95,14 @@ /** * go from this: - * <img src=".../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> + * <img src="http[s]://.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> * * to this: * - * <IMG src="cid:smiley-cool.gif"/> + * <img src="/path/on/server/.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> * ... - * ------part... - * Content-Type: image/gif - * Content-Transfer-Encoding: base64 - * Content-ID: <smiley-cool.gif> */ -function rcmail_attach_emoticons(&$mime_message) +function rcmail_fix_emoticon_paths(&$mime_message) { global $CONFIG; @@ -149,10 +145,10 @@ return $body; } -// parse email address input -function rcmail_email_input_format($mailto) +// parse email address input (and count addresses) +function rcmail_email_input_format($mailto, $count=false) { - global $EMAIL_FORMAT_ERROR; + global $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT; $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U'); $replace = array(', ', ', ', '', ',', '\\1 \\2'); @@ -197,6 +193,10 @@ } } + if ($count) { + $RECIPIENT_COUNT += count($result); + } + return implode(', ', $result); } @@ -205,17 +205,18 @@ if (strlen($_POST['_draft_saveid']) > 3) $olddraftmessageid = get_input_value('_draft_saveid', RCUBE_INPUT_POST); -$message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.mt_rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host'])); +$message_id = rcmail_gen_message_id(); // set default charset $input_charset = $OUTPUT->get_charset(); $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset; $EMAIL_FORMAT_ERROR = NULL; +$RECIPIENT_COUNT = 0; -$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset)); -$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset)); -$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset)); +$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset), true); +$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset), true); +$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset), true); if ($EMAIL_FORMAT_ERROR) { $OUTPUT->show_message('emailformaterror', 'error', array('email' => $EMAIL_FORMAT_ERROR)); @@ -248,7 +249,7 @@ // if configured, the Received headers goes to top, for good measure if ($CONFIG['http_received_header']) { - $nldlm = $RCMAIL->config->header_delimiter() . "\t"; + $nldlm = "\r\n\t"; // FROM/VIA $http_header = 'from '; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { @@ -286,7 +287,7 @@ $headers['Received'] = $http_header; } -$headers['Date'] = date('r'); +$headers['Date'] = rcmail_user_date(); $headers['From'] = rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset); $headers['To'] = $mailto; @@ -297,8 +298,17 @@ if (!empty($mailbcc)) $headers['Bcc'] = $mailbcc; -if (!empty($identity_arr['bcc'])) +if (!empty($identity_arr['bcc'])) { $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc']; + $RECIPIENT_COUNT ++; +} + +if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) { + if ($RECIPIENT_COUNT > $max_recipients) { + $OUTPUT->show_message('toomanyrecipients', 'error', array('max' => $max_recipients)); + $OUTPUT->send('iframe'); + } +} // add subject $headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, TRUE, $message_charset)); @@ -348,7 +358,7 @@ $headers['User-Agent'] = $CONFIG['useragent']; // exec hook for header checking and manipulation -$data = $RCMAIL->plugins->exec_hook('outgoing_message_headers', array('headers' => $headers)); +$data = $RCMAIL->plugins->exec_hook('message_outgoing_headers', array('headers' => $headers)); // sending aborted by plugin if ($data['abort'] && !$savedraft) { @@ -359,32 +369,45 @@ $headers = $data['headers']; -$isHtmlVal = strtolower(get_input_value('_is_html', RCUBE_INPUT_POST)); -$isHtml = ($isHtmlVal == "1"); +$isHtml = (bool) get_input_value('_is_html', RCUBE_INPUT_POST); // fetch message body $message_body = get_input_value('_message', RCUBE_INPUT_POST, TRUE, $message_charset); if (!$savedraft) { - // remove signature's div ID - if ($isHtml) + if ($isHtml) { + // remove signature's div ID $message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body); + // add inline css for blockquotes + $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%'; + $message_body = preg_replace('/<blockquote>/', + '<blockquote type="cite" style="'.$bstyle.'">', $message_body); + } + // generic footer for all messages - if (!empty($CONFIG['generic_message_footer'])) { + if ($isHtml && !empty($CONFIG['generic_message_footer_html'])) { + $footer = file_get_contents(realpath($CONFIG['generic_message_footer_html'])); + $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset); + } + else if (!empty($CONFIG['generic_message_footer'])) { $footer = file_get_contents(realpath($CONFIG['generic_message_footer'])); $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset); + if ($isHtml) + $footer = '<pre>'.$footer.'</pre>'; } + if ($footer) + $message_body .= "\r\n" . $footer; } // set line length for body wrapping -$LINE_LENGTH = $RCMAIL->config->get('line_length', 75); +$LINE_LENGTH = $RCMAIL->config->get('line_length', 72); // Since we can handle big messages with disk usage, we need more time to work @set_time_limit(0); // create PEAR::Mail_mime instance -$MAIL_MIME = new Mail_mime($RCMAIL->config->header_delimiter()); +$MAIL_MIME = new Mail_mime("\r\n"); // Check if we have enough memory to handle the message in it // It's faster than using files, so we'll do this if we only can @@ -405,35 +428,52 @@ // the HTML part and the plain-text part if ($isHtml) { - $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME)); - $MAIL_MIME->setHTMLBody($plugin['body'] . ($footer ? "\r\n<pre>".$footer.'</pre>' : '')); + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME)); + + $MAIL_MIME->setHTMLBody($plugin['body']); // add a plain text version of the e-mail as an alternative part. $h2t = new html2text($plugin['body'], false, true, 0); - $plainTextPart = rc_wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n") . ($footer ? "\r\n".$footer : ''); + $plainTextPart = rc_wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n"); $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true); - if (!strlen($plainTextPart)) { + if (!$plainTextPart) { // empty message body breaks attachment handling in drafts $plainTextPart = "\r\n"; } - $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME)); + else { + // make sure all line endings are CRLF (#1486712) + $plainTextPart = preg_replace('/\r?\n/', "\r\n", $plainTextPart); + } + + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME)); + $MAIL_MIME->setTXTBody($plugin['body']); - // look for "emoticon" images from TinyMCE and copy into message as attachments - $message_body = rcmail_attach_emoticons($MAIL_MIME); + // look for "emoticon" images from TinyMCE and change their src paths to + // be file paths on the server instead of URL paths. + $message_body = rcmail_fix_emoticon_paths($MAIL_MIME); } -else - { - $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n"); - if ($footer) - $message_body .= "\r\n" . $footer; +else { + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME)); + + $message_body = $plugin['body']; + + // compose format=flowed content if enabled + if ($flowed = $RCMAIL->config->get('send_format_flowed', true)) + $message_body = rcube_message::format_flowed($message_body, min($LINE_LENGTH+2, 79)); + else + $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n"); + $message_body = wordwrap($message_body, 998, "\r\n", true); if (!strlen($message_body)) { // empty message body breaks attachment handling in drafts $message_body = "\r\n"; } - $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME)); - $MAIL_MIME->setTXTBody($plugin['body'], false, true); + + $MAIL_MIME->setTXTBody($message_body, false, true); } // add stored attachments, if any @@ -441,14 +481,14 @@ { foreach ($_SESSION['compose']['attachments'] as $id => $attachment) { // This hook retrieves the attachment contents from the file storage backend - $attachment = $RCMAIL->plugins->exec_hook('get_attachment', $attachment); + $attachment = $RCMAIL->plugins->exec_hook('attachment_get', $attachment); - $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]\s*/'; + $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); $MAIL_MIME->setHTMLBody($message_body); - + if ($attachment['data']) $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false); else @@ -463,9 +503,7 @@ $ctype, $attachment['name'], ($attachment['data'] ? false : true), - // @TODO: quoted-printable for message/rfc822 is safe, - // but we should check that 7bit or 8bit is possible here - ($ctype == 'message/rfc822' ? 'quoted-printable' : 'base64'), + ($ctype == 'message/rfc822' ? '8bit' : 'base64'), ($ctype == 'message/rfc822' ? 'inline' : 'attachment'), $message_charset, '', '', $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, @@ -487,14 +525,14 @@ $MAIL_MIME->setParam('head_encoding', 'quoted-printable'); $MAIL_MIME->setParam('head_charset', $message_charset); $MAIL_MIME->setParam('html_charset', $message_charset); -$MAIL_MIME->setParam('text_charset', $message_charset); +$MAIL_MIME->setParam('text_charset', $message_charset . ($flowed ? ";\r\n format=flowed" : '')); // encoding subject header with mb_encode provides better results with asian characters if (function_exists('mb_encode_mimeheader')) { mb_internal_encoding($message_charset); $headers['Subject'] = mb_encode_mimeheader($headers['Subject'], - $message_charset, 'Q', $RCMAIL->config->header_delimiter(), 8); + $message_charset, 'Q', "\r\n", 8); mb_internal_encoding(RCMAIL_CHARSET); } @@ -548,17 +586,14 @@ if ($store_target) { - // check if mailbox exists - if (!in_array($store_target, $IMAP->list_mailboxes())) - { - // folder may be existing but not subscribed (#1485241) - if (!in_array($store_target, $IMAP->list_unsubscribed())) - $store_folder = $IMAP->create_mailbox($store_target, TRUE); - else if ($IMAP->subscribe($store_target)) - $store_folder = TRUE; - } - else - $store_folder = TRUE; + // check if folder is subscribed + if ($IMAP->mailbox_exists($store_target, true)) + $store_folder = true; + // folder may be existing but not subscribed (#1485241) + else if (!$IMAP->mailbox_exists($store_target)) + $store_folder = $IMAP->create_mailbox($store_target, true); + else if ($IMAP->subscribe($store_target)) + $store_folder = true; // append message to sent box if ($store_folder) { @@ -612,9 +647,9 @@ if ($olddraftmessageid) { // delete previous saved draft - $a_deleteid = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$olddraftmessageid); - - $deleted = $IMAP->delete_message($IMAP->get_uid($a_deleteid[0], $CONFIG['drafts_mbox']), $CONFIG['drafts_mbox']); + $a_deleteid = $IMAP->search_once($CONFIG['drafts_mbox'], + 'HEADER Message-ID '.$olddraftmessageid, true); + $deleted = $IMAP->delete_message($a_deleteid, $CONFIG['drafts_mbox']); // raise error if deletion of old draft failed if (!$deleted) @@ -634,8 +669,8 @@ $msgid = strtr($message_id, array('>' => '', '<' => '')); // remember new draft-uid - $draftids = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid); - $_SESSION['compose']['param']['_draft_uid'] = $IMAP->get_uid($draftids[0], $CONFIG['drafts_mbox']); + $draftuids = $IMAP->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid, true); + $_SESSION['compose']['param']['_draft_uid'] = $draftuids[0]; // display success $OUTPUT->show_message('messagesaved', 'confirmation'); @@ -660,4 +695,4 @@ $OUTPUT->send('iframe'); } -?> + -- Gitblit v1.9.1