X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=functions%2Fmime.php;h=bcd174090636b6b2fb5427085cec4e5f7b4bef7c;hp=8843d2591a8f898e3328ac1cccfb9c6ad87e8a05;hb=84edf699d419494324e08176c89e9fbfc5a23818;hpb=10c0caeba56ea1e7944fecbe1e71c0cbf4d29187 diff --git a/functions/mime.php b/functions/mime.php index 8843d259..bcd17409 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -6,7 +6,7 @@ * This contains the functions necessary to detect and decode MIME * messages. * - * @copyright © 1999-2007 The SquirrelMail Project Team + * @copyright 1999-2009 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail @@ -92,6 +92,9 @@ function mime_structure ($bodystructure, $flags=array()) { if (strtolower($flag) == '\\flagged') { $msg->is_flagged = true; } + else if (strtolower($flag) == '$forwarded') { + $msg->is_forwarded = true; + } break; case 'M': if (strtolower($flag) == '$mdnsent') { @@ -137,7 +140,7 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1, $fetch_size=0) { } while($topline && ($topline[0] == '*') && !preg_match('/\* [0-9]+ FETCH.*/i', $topline)) ; $wholemessage = implode('', $data); - if (ereg('\\{([^\\}]*)\\}', $topline, $regs)) { + if (preg_match('/\{([^\}]*)\}/', $topline, $regs)) { $ret = substr($wholemessage, 0, $regs[1]); /* There is some information in the content info header that could be important * in order to parse html messages. Let's get them here. @@ -145,7 +148,7 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1, $fetch_size=0) { // if ($ret{0} == '<') { // $data = sqimap_run_command ($imap_stream, "FETCH $id BODY[$ent_id.MIME]", true, $response, $message, TRUE); // } - } else if (ereg('"([^"]*)"', $topline, $regs)) { + } else if (preg_match('/"([^"]*)"/', $topline, $regs)) { $ret = $regs[1]; } else if ((stristr($topline, 'nil') !== false) && (empty($wholemessage))) { $ret = $wholemessage; @@ -181,7 +184,7 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1, $fetch_size=0) { return $ret; } -function mime_print_body_lines ($imap_stream, $id, $ent_id=1, $encoding, $rStream='php://stdout') { +function mime_print_body_lines ($imap_stream, $id, $ent_id=1, $encoding, $rStream='php://stdout', $force_crlf='') { /* Don't kill the connection if the browser is over a dialup * and it would take over 30 seconds to download it. @@ -203,9 +206,9 @@ function mime_print_body_lines ($imap_stream, $id, $ent_id=1, $encoding, $rStrea } else { $body = mime_fetch_body ($imap_stream, $id, $ent_id); if (is_resource($rStream)) { - fputs($rStream,decodeBody($body,$encoding)); + fputs($rStream,decodeBody($body, $encoding, $force_crlf)); } else { - echo decodeBody($body, $encoding); + echo decodeBody($body, $encoding, $force_crlf); } } @@ -291,7 +294,8 @@ function translateText(&$body, $wrap_at, $charset) { $body_ary = explode("\n", $body); for ($i=0; $i < count($body_ary); $i++) { - $line = $body_ary[$i]; + $line = rtrim($body_ary[$i],"\r"); + if (strlen($line) - 2 >= $wrap_at) { sqWordWrap($line, $wrap_at, $charset); } @@ -342,10 +346,9 @@ function translateText(&$body, $wrap_at, $charset) { * @param string $ent_num (since 1.3.0) message part id * @param integer $id (since 1.3.0) message id * @param string $mailbox (since 1.3.0) imap folder name - * @param boolean $clean (since 1.5.1) Do not output stuff that's irrelevant for the printable version. * @return string html formated message text */ -function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $mailbox='INBOX', $clean=FALSE) { +function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $mailbox='INBOX') { /* This if statement checks for the entity to show as the * primary message. To add more of them, just put them in the * order that is their priority. @@ -359,9 +362,9 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma // workaround for not updated config.php if (! isset($use_iframe)) $use_iframe = false; - if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) { - $view_unsafe_images = false; - } + // If there's no "view_unsafe_images" variable in the URL, turn unsafe + // images off by default. + sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE); $body = ''; $urlmailbox = urlencode($mailbox); @@ -401,9 +404,7 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma $body = trim($body); translateText($body, $wrap_at, $body_message->header->getParameter('charset')); - } elseif ($use_iframe && ! $clean) { - // $clean is used to remove iframe in printable view. - + } elseif ($use_iframe) { /** * If we don't add html message between iframe tags, * we must detect unsafe images and modify $has_unsafe_images. @@ -443,13 +444,20 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma $body_message->header->getParameter('charset')); } - // if this is the clean display (i.e. printer friendly), stop here. - if ( $clean ) { - return $body; - } + /* + * Previously the links for downloading and unsafe images were printed + * under the mail. By putting the links in a global variable we can + * print it in the toolbar where it belongs. Since the original code was + * in this place it's left here. It might be possible to move it to some + * other place if that makes sense. The possibility to do so has not + * been evaluated yet. + */ + // Initialize the global variable to an empty string. + // FIXME: To have $download_and_unsafe_link as a global variable might not be needed since the use of separate variables ($download_href, $unsafe_image_toggle_href, and $unsafe_image_toggle_text) for the templates was introduced. $download_and_unsafe_link = ''; + // Prepare and build a link for downloading the mail. $link = 'passed_id=' . $id . '&ent_id='.$ent_num. '&mailbox=' . $urlmailbox .'&sort=' . $sort . '&startMessage=' . $startMessage . '&show_more=0'; @@ -457,8 +465,16 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma $link .= '&passed_ent_id='.$passed_ent_id; } $download_href = SM_PATH . 'src/download.php?absolute_dl=true&' . $link; + + // Always add the link for downloading the mail as a file to the global + // variable. $download_and_unsafe_link .= "$nbsp|$nbsp" . create_hyperlink($download_href, _("Download this as a file")); + + // Find out the right text to use in the link depending on the + // circumstances. If the unsafe images are displayed the link should + // hide them, if they aren't displayed the link should only appear if + // the mail really contains unsafe images. if ($view_unsafe_images) { $text = _("Hide Unsafe Images"); } else { @@ -469,6 +485,9 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma $text = ''; } } + + // Only create a link for unsafe images if there's need for one. If so: + // add it to the global variable. if($text != '') { $unsafe_image_toggle_href = SM_PATH . 'src/read_body.php?'.$link; $unsafe_image_toggle_text = $text; @@ -480,9 +499,7 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma } /** - * Generate attachments array for passing to templates. Separated from - * formatAttachments() below so that the same array can be given to the - * print-friendly version. + * Generate attachments array for passing to templates. * * @since 1.5.2 * @param object $message SquirrelMail message object @@ -675,44 +692,79 @@ function sqimap_base64_decode(&$string) { } /** - * Decodes encoded message body + * Decodes encoded string (usually message body) + * + * This function decodes a string (usually the message body) + * depending on the encoding type. Currently quoted-printable + * and base64 encodings are supported. + * + * The decode_body hook was added to this function in 1.4.2/1.5.0. + * The $force_crlf parameter was added in 1.5.2. + * + * @param string $string The encoded string + * @param string $encoding used encoding + * @param string $force_crlf Whether or not to force CRLF or LF + * line endings (or to leave as is). + * If given as "LF", line endings will + * all be converted to LF; if "CRLF", + * line endings will all be converted + * to CRLF. If given as an empty value, + * the global $force_crlf_default will + * be consulted (it can be specified in + * config/config_local.php). Otherwise, + * any other value will cause the string + * to be left alone. Note that this will + * be overridden to "LF" if not using at + * least PHP version 4.3.0. (OPTIONAL; + * default is empty - consult global + * default value) + * + * @return string The decoded string * - * This function decodes the body depending on the encoding type. - * Currently quoted-printable and base64 encodings are supported. - * decode_body hook was added to this function in 1.4.2/1.5.0 - * @param string $body encoded message body - * @param string $encoding used encoding - * @return string decoded string * @since 1.0 + * */ -function decodeBody($body, $encoding) { +function decodeBody($string, $encoding, $force_crlf='') { + + global $force_crlf_default; + if (empty($force_crlf)) $force_crlf = $force_crlf_default; + $force_crlf = strtoupper($force_crlf); + + // must force line endings to LF due to broken + // quoted_printable_decode() in PHP versions + // before 4.3.0 (see below) + // + if (!check_php_version(4, 3, 0) || $force_crlf == 'LF') + $string = str_replace("\r\n", "\n", $string); + else if ($force_crlf == 'CRLF') + $string = str_replace("\n", "\r\n", $string); - $body = str_replace("\r\n", "\n", $body); $encoding = strtolower($encoding); $encoding_handler = do_hook('decode_body', $encoding); - // plugins get first shot at decoding the body + // plugins get first shot at decoding the string // if (!empty($encoding_handler) && function_exists($encoding_handler)) { - $body = $encoding_handler('decode', $body); + $string = $encoding_handler('decode', $string); } elseif ($encoding == 'quoted-printable' || $encoding == 'quoted_printable') { - /** - * quoted_printable_decode() function is broken in older - * php versions. Text with \r\n decoding was fixed only - * in php 4.3.0. Minimal code requirement 4.0.4 + - * str_replace("\r\n", "\n", $body); call. - */ - $body = quoted_printable_decode($body); + + // quoted_printable_decode() function is broken in older + // php versions. Text with \r\n decoding was fixed only + // in php 4.3.0. Minimal code requirement is PHP 4.0.4+ + // and the above call to: str_replace("\r\n", "\n", $string); + // + $string = quoted_printable_decode($string); + } elseif ($encoding == 'base64') { - $body = base64_decode($body); + $string = base64_decode($string); } // All other encodings are returned raw. - return $body; + return $string; } /** @@ -1829,9 +1881,10 @@ function sq_fix_url($attname, &$attvalue, $message, $id, $mailbox,$sQuote = '"') $attvalue = trim(substr($attvalue,1,-1)); } - if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) { - $view_unsafe_images = false; - } + // If there's no "view_unsafe_images" variable in the URL, turn unsafe + // images off by default. + sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE); + $secremoveimg = '../images/' . _("sec_remove_eng.png"); /** @@ -1866,15 +1919,72 @@ function sq_fix_url($attname, &$attvalue, $message, $id, $mailbox,$sQuote = '"') $attvalue = $sQuote . $secremoveimg . $sQuote; } else { if (isset($aUrl['path'])) { + + // No one has been able to show that image URIs + // can be exploited, so for now, no restrictions + // are made at all. If this proves to be a problem, + // the commented-out code below can be of help. + // (One consideration is that I see nothing in this + // function that specifically says that we will + // only ever arrive here when inspecting an image + // tag, although that does seem to be the end + // result - e.g.,