X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fmime.php;h=a08920ca252b681759f5d6068e8268f653103a55;hb=1d398b1de56b0695e1a8dd26621f5be9399a9669;hp=f89aa54606875663c2d9cbe98ecab6768a147e67;hpb=9ebace193471e0957e523805e59e8676a831c2b7;p=squirrelmail.git diff --git a/functions/mime.php b/functions/mime.php index f89aa546..a08920ca 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-2011 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,12 +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 there's no "view_unsafe_images" setting in the user's preferences, - // turn unsafe images off by default. - // FIXME: Check if the UIR plugin is enabled. If it's not, no unsafe images should be displayed regardless of the user's preferences. This test is done in several places in the code and they should all be fixed in the same way. - 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); @@ -404,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. @@ -446,11 +444,6 @@ 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 @@ -506,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 @@ -584,9 +575,9 @@ function buildAttachmentArray($message, $exclude_id, $mailbox, $id) { } /* This executes the attachment hook with a specific MIME-type. - * If that doesn't have results, it tries if there's a rule - * for a more generic type. Finally, a hook for ALL attachment - * types is run as well. + * It also allows plugins to run if there's a rule for a more + * generic type. Finally, a hook for ALL attachment types is + * run as well. */ // First remember the default link. $defaultlink_orig = $defaultlink; @@ -596,19 +587,23 @@ function buildAttachmentArray($message, $exclude_id, $mailbox, $id) { argument, and arguments are passed by reference, so instead of returning any changes, changes should simply be made to the original arguments themselves. */ - $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent, + $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent, &$defaultlink, &$display_filename, &$where, &$what); do_hook("attachment $type0/$type1", $temp); - if(count($links) <= 1 && $defaultlink == $defaultlink_orig) { - /* The API for this hook has changed as of 1.5.2 so that all plugin - arguments are passed in an array instead of each their own plugin - argument, and arguments are passed by reference, so instead of - returning any changes, changes should simply be made to the original - arguments themselves. */ - $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent, - &$defaultlink, &$display_filename, &$where, &$what); - do_hook("attachment $type0/*", $temp); + /* The API for this hook has changed as of 1.5.2 so that all plugin + arguments are passed in an array instead of each their own plugin + argument, and arguments are passed by reference, so instead of + returning any changes, changes should simply be made to the original + arguments themselves. */ + $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent, + &$defaultlink, &$display_filename, &$where, &$what); + // Do not let a generic plugin change the default link if a more + // specialized one already did it... + if ($defaultlink != $defaultlink_orig) { + $dummy = ''; + $temp[5] = &$dummy; } + do_hook("attachment $type0/*", $temp); /* The API for this hook has changed as of 1.5.2 so that all plugin arguments are passed in an array instead of each their own plugin argument, and arguments are passed by reference, so instead of @@ -701,44 +696,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; } /** @@ -932,6 +962,7 @@ function encodeHeader ($string) { for($i = 0; $i < $j; ++$i) { switch($string{$i}) { + case '"': case '=': case '<': case '>': @@ -1855,12 +1886,10 @@ function sq_fix_url($attname, &$attvalue, $message, $id, $mailbox,$sQuote = '"') $attvalue = trim(substr($attvalue,1,-1)); } - // If there's no "view_unsafe_images" setting in the user's preferences, - // turn unsafe images off by default. - // FIXME: Check if the UIR plugin is enabled. If it's not, no unsafe images should be displayed regardless of the user's preferences. This test is done in several places in the code and they should all be fixed in the same way. - 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"); /** @@ -1895,15 +1924,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.,