X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;ds=sidebyside;f=functions%2Fmime.php;h=278c0d95f429ab9b3968ae07ed05641b45ca3599;hb=358f007e212ad7428914c505f44f9ac192465224;hp=4c1930b728732796ff28ad06312b9a122824d708;hpb=377a40b2b1d2df34b77f5e35bf4493fd1c1ee748;p=squirrelmail.git diff --git a/functions/mime.php b/functions/mime.php index 4c1930b7..278c0d95 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -6,17 +6,15 @@ ** ** $Id$ **/ + + if (defined('mime_php')) + return; + define('mime_php', true); + global $debug_mime; $debug_mime = false; - $mime_php = true; - - if (!isset($i18n_php)) - include "../functions/i18n.php"; - if (!isset($imap_php)) - include "../functions/imap.php"; - if (!isset($config_php)) - include "../config/config.php"; - + + include "../functions/imap.php"; /** Setting up the objects that have the structure for the message **/ @@ -28,7 +26,7 @@ var $encoding = '', $size = 0, $to = array(), $from = '', $date = ''; var $cc = array(), $bcc = array(), $reply_to = '', $subject = ''; var $id = 0, $mailbox = '', $description = '', $filename = ''; - var $entity_id = 0, $message_id = 0; + var $entity_id = 0, $message_id = 0, $name = ''; } class message { @@ -122,8 +120,8 @@ $msg = mime_get_element ($structure, $msg, $ent_id); if ($debug_mime) echo "
"; } - return $msg; if ($debug_mime) echo "  END: mime_parse_structure()
"; + return $msg; } // Increments the element ID. An element id can look like any of @@ -161,6 +159,7 @@ $elem_num = 1; $msg->header = new msg_header(); $msg->header->entity_id = $ent_id; + $properties = array(); while (strlen($structure) > 0) { $structure = trim($structure); @@ -184,8 +183,6 @@ // comment me $end = mime_match_parenthesis (0, $structure); $sub = substr($structure, 1, $end-1); - if (! isset($properties)) - $properties = array(); $properties = mime_get_props($properties, $sub); $structure = substr($structure, strlen($sub) + 2); } else { @@ -352,6 +349,8 @@ // ignore all extra characters // If inside of a string, skip string -- Boundary IDs and other // things can have ) in them. + if ($char != '(') + return strlen($structure); while ($pos < strlen($structure)) { $pos++; $char = substr($structure, $pos, 1); @@ -383,7 +382,7 @@ fputs ($imap_stream, "a010 FETCH $id BODY[$ent_id]\r\n"); $data = sqimap_read_data ($imap_stream, 'a010', true, $response, $message); $topline = array_shift($data); - while (! ereg('\\* [0-9]+ FETCH ', $topline) && data) + while (! ereg('\\* [0-9]+ FETCH ', $topline) && $data) $topline = array_shift($data); $wholemessage = implode('', $data); @@ -404,8 +403,6 @@ $str .= htmlspecialchars($d) . "\n"; } return $str; - - return "Body retrival error, please report this bug!\n\nTop line is \"$topline\"\n"; } function mime_print_body_lines ($imap_stream, $id, $ent_id, $encoding) { @@ -413,10 +410,16 @@ // that it is the first one. That is usually the case anyway. if (!$ent_id) $ent_id = 1; + // Don't kill the connection if the browser is over a dialup + // and it would take over 30 seconds to download it. + set_time_limit(0); + fputs ($imap_stream, "a001 FETCH $id BODY[$ent_id]\r\n"); $cnt = 0; $continue = true; $read = fgets ($imap_stream,4096); + // This could be bad -- if the section has 'a001 OK' + // or similar, it will kill the download. while (!ereg("^a001 (OK|BAD|NO)(.*)$", $read, $regs)) { if (trim($read) == ")==") { $read1 = $read; @@ -478,21 +481,49 @@ // figures out what entity to display and returns the $message object // for that entity. - function findDisplayEntity ($message) { - if ($message) { - if ($message->header->type0 == "text") { - if ($message->header->type1 == "plain" || - $message->header->type1 == "html") { - if (isset($message->header->entity_id)) - return $message->header->entity_id; - return 0; - } - } else { - for ($i=0; $message->entities[$i]; $i++) { - return findDisplayEntity($message->entities[$i]); - } - } + function findDisplayEntity ($message, $textOnly = 1) + { + global $show_html_default; + + if (! $message) + return 0; + + if ($message->header->type0 == "multipart" && + $message->header->type1 == "alternative" && + $show_html_default && ! $textOnly) { + $entity = findDisplayEntityHTML($message); + if ($entity != 0) + return $entity; + } + + // Show text/plain or text/html -- the first one we find. + if ($message->header->type0 == 'text' && + ($message->header->type1 == 'plain' || + $message->header->type1 == 'html') && + isset($message->header->entity_id)) + return $message->header->entity_id; + + for ($i=0; isset($message->entities[$i]); $i++) { + $entity = findDisplayEntity($message->entities[$i], $textOnly); + if ($entity != 0) + return $entity; } + + return 0; + } + + // Shows the HTML version + function findDisplayEntityHTML ($message) { + if ($message->header->type0 == 'text' && + $message->header->type1 == 'html' && + isset($message->header->entity_id)) + return $message->header->entity_id; + for ($i = 0; isset($message->entities[$i]); $i ++) { + $entity = findDisplayEntityHTML($message->entities[$i]); + if ($entity != 0) + return $entity; + } + return 0; } /** This returns a parsed string called $body. That string can then @@ -510,7 +541,8 @@ $urlmailbox = urlencode($message->header->mailbox); // Get the right entity and redefine message to be this entity - $ent_num = findDisplayEntity ($message); + // Pass the 0 to mean that we want the 'best' viewable one + $ent_num = findDisplayEntity ($message, 0); $body_message = getEntity($message, $ent_num); if (($body_message->header->type0 == "text") || ($body_message->header->type0 == "rfc822")) { @@ -524,15 +556,16 @@ translateText($body, $wrap_at, $body_message->header->charset); } - $body .= "
". _("Download this as a file") ."

"; + $body .= "
". _("Download this as a file") ."

"; /** Display the ATTACHMENTS: message if there's more than one part **/ $body .= ""; if (isset($message->entities[0])) { $body .= formatAttachments ($message, $ent_num, $message->header->mailbox, $id); } + $body .= ""; } else { - $body .= formatAttachments ($message, -1, $message->header->mailbox, $id); + $body = formatAttachments ($message, -1, $message->header->mailbox, $id); } return $body; } @@ -567,11 +600,17 @@ if (!$message->entities) { $type0 = strtolower($message->header->type0); $type1 = strtolower($message->header->type1); + $name = decodeHeader($message->header->name); if ($message->header->entity_id != $ent_id) { $filename = decodeHeader($message->header->filename); if (trim($filename) == "") { - $display_filename = "untitled-".$message->header->entity_id; + if (trim($name) == "") { + $display_filename = "untitled-".$message->header->entity_id; + } else { + $display_filename = $name; + $filename = $name; + } } else { $display_filename = $filename; } @@ -640,6 +679,8 @@ $body = str_replace("\r\n", "\n", $body); $encoding = strtolower($encoding); + global $show_html_default; + if ($encoding == "quoted-printable") { $body = quoted_printable_decode($body); @@ -649,6 +690,13 @@ $body = base64_decode($body); } + if (!$show_html_default) { + $body = str_replace('<', '<', $body); +// $body = str_replace('>', '>', $body); +// Both this and $body = htmlspecialchars($body); mess up inline +// quoting :-( Anyway, just replacing < gets the job done. + } + // All other encodings are returned raw. return $body; } @@ -665,7 +713,7 @@ $replace = ereg_replace("_", " ", $res[3]); // Convert lowercase Quoted Printable to uppercase for // quoted_printable_decode to understand it. - while (ereg("(=([0-9][abcdef])|([abcdef][0-9])|([abcdef][abcdef]))", $replace, $res)) { + while (ereg("(=(([0-9][abcdef])|([abcdef][0-9])|([abcdef][abcdef])))", $replace, $res)) { $replace = str_replace($res[1], strtoupper($res[1]), $replace); } $replace = quoted_printable_decode($replace); @@ -673,9 +721,10 @@ $replace = charset_decode ($res[1], $replace); - $string = eregi_replace - ('=\\?([^?]+)\\?(q|b)\\?([^?]+)\\?=', + // Remove the name of the character set. + $string = eregi_replace ('=\\?([^?]+)\\?(q|b)\\?([^?]+)\\?=', $replace, $string); + // In case there should be more encoding in the string: recurse return (decodeHeader($string)); } else @@ -687,30 +736,40 @@ // be encoded. function encodeHeader ($string) { global $default_charset; - - // Encode only if the string contains 8-bit characters or =? - if (ereg("([\200-\377]|=\\?)", $string)) { - $newstring = "=?$default_charset?Q?"; - - // First the special characters - $string = str_replace("=", "=3D", $string); - $string = str_replace("?", "=3F", $string); - $string = str_replace("_", "=5F", $string); - $string = str_replace(" ", "_", $string); - - for ( $ch = 127 ; $ch <= 255 ; $ch++ ) { - $replace = chr($ch); - $insert = sprintf("=%02X", $ch); - $string = str_replace($replace, $insert, $string); - $ch++; - } - - $newstring = "=?$default_charset?Q?".$string."?="; - - return $newstring; - } - - return $string; - } + + // Encode only if the string contains 8-bit characters or =? + $j = strlen( $string ); + $l = FALSE; // Must be encoded ? + $ret = ''; + for( $i=0; $i < $j; ++$i) { + switch( $string{$i} ) { + case '=': + $ret .= '=3D'; + break; + case '?': + $l = TRUE; + $ret .= '=3F'; + break; + case '_': + $ret .= '=5F'; + break; + case ' ': + $ret .= '_'; + break; + default: + $k = ord( $string{$i} ); + if( $k > 126 ) { + $ret .= sprintf("=%02X", $k); + $l = TRUE; + } else + $ret .= $string{$i}; + } + } + + if( $l ) + $string = "=?$default_charset?Q?$ret?="; + + return( $string ); + } ?>