X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fmime.php;h=4451dbfce8ea27ca42d8cafbb444243ca782a991;hb=88104625cc762185b3361f1b347c89900280e2e4;hp=194f82fc5012bb672528a3218b1ee99c26e113af;hpb=ae35570be65355e07d7c5159f9e883d5f5c9fdb3;p=squirrelmail.git diff --git a/functions/mime.php b/functions/mime.php index 194f82fc..4451dbfc 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -24,7 +24,7 @@ class msg_header { $encoding = '', $size = 0, $to = array(), $from = '', $date = '', $cc = array(), $bcc = array(), $reply_to = '', $subject = '', $id = 0, $mailbox = '', $description = '', $filename = '', - $entity_id = 0, $message_id = 0, $name = '', $priority = 3; + $entity_id = 0, $message_id = 0, $name = '', $priority = 3, $type = ''; } class message { @@ -68,6 +68,7 @@ function mime_structure ($imap_stream, $header) { // isolate the body structure and remove beginning and end parenthesis $read = trim(substr ($read, strpos(strtolower($read), 'bodystructure') + 13)); + $read = trim(substr ($read, 0, -1)); $end = mime_match_parenthesis(0, $read); while ($end == strlen($read)-1) { @@ -91,23 +92,51 @@ function mime_structure ($imap_stream, $header) { * to mime_get_elements() */ function mime_parse_structure ($structure, $ent_id) { - + $properties = array(); $msg = new message(); if ($structure{0} == '(') { + $old_ent_id = $ent_id; $ent_id = mime_new_element_level($ent_id); $start = $end = -1; do { $start = $end+1; $end = mime_match_parenthesis ($start, $structure); + /* add "forgotten" parent entities (alternative and relative) */ + if (strpos($ent_id, '0') || strpos($ent_id, '0') == 0) { + $str = substr($structure, $end+1 ); + $startprop = strrpos($str,'('); + $endprop = strrpos($str,')'); + $propstr = substr($str, $startprop + 1, ($endprop - $startprop)-1); + + $type1 = trim(substr($str,0, $startprop)); + $pos = strrpos($type1,' '); + $type1 = strtolower(trim(substr($type1,$pos +1))); + $cnt = strlen($type1); + $type1 = substr($type1,0,$cnt-1); + + $properties = mime_get_props($properties, $propstr); + if (count($properties)>0) { + $msg->header->entity_id = $old_ent_id; + $msg->header->type0 = 'multipart'; + $msg->header->type1 = $type1; + } + for ($i=0; $i < count($properties); $i++) { + $msg->header->{$properties[$i]['name']} = $properties[$i]['value']; + $name = $properties[$i]['name']; + $value = $properties[$i]['value']; + } + } $element = substr($structure, $start+1, ($end - $start)-1); + $ent_id = mime_increment_id ($ent_id); $newmsg = mime_parse_structure ($element, $ent_id); $msg->addEntity ($newmsg); + } while ($structure{$end+1} == '('); } else { // parse the elements - $msg = mime_get_element ($structure, $msg, $ent_id); + $msg = mime_get_element ($structure, $msg, $ent_id); } return $msg; } @@ -155,7 +184,6 @@ function mime_get_element (&$structure, $msg, $ent_id) { $msg->header = new msg_header(); $msg->header->entity_id = $ent_id; $properties = array(); - while (strlen($structure) > 0) { $structure = trim($structure); $char = $structure{0}; @@ -251,11 +279,9 @@ function mime_get_element (&$structure, $msg, $ent_id) { $text = ""; } // loop through the additional properties and put those in the various headers -// if ($msg->header->type0 != 'message') { - for ($i=0; $i < count($properties); $i++) { - $msg->header->{$properties[$i]['name']} = $properties[$i]['value']; - } -// } + for ($i=0; $i < count($properties); $i++) { + $msg->header->{$properties[$i]['name']} = $properties[$i]['value']; + } return $msg; } @@ -281,7 +307,6 @@ function mime_get_props ($props, $structure) { while (strlen($structure) > 0) { $structure = trim($structure); $char = $structure{0}; - if ($char == '"') { $pos = 1; $tmp = ''; @@ -301,20 +326,24 @@ function mime_get_props ($props, $structure) { $value .= $char; $pos++; } - $structure = trim(substr($structure, strlen($tmp) + 2)); - + $structure = trim(substr($structure, strlen($value) + 2)); $k = count($props); $props[$k]['name'] = strtolower($tmp); $props[$k]['value'] = $value; + if ($structure != '') { + mime_get_props($props, $structure); + } else { + return $props; + } } else if ($char == '(') { $end = mime_match_parenthesis (0, $structure); $sub = substr($structure, 1, $end-1); - if (! isset($props)) - $props = array(); - $props = mime_get_props($props, $sub); - $structure = substr($structure, strlen($sub) + 2); + if (! isset($props)) + $props = array(); + $props = mime_get_props($props, $sub); + $structure = substr($structure, strlen($sub) + 2); + return $props; } - return $props; } else if ($char == '(') { $end = mime_match_parenthesis (0, $structure); $sub = substr($structure, 1, $end-1); @@ -382,8 +411,8 @@ function mime_fetch_body($imap_stream, $id, $ent_id ) { $data = sqimap_run_command ($imap_stream, $cmd, true, $response, $message); do { - $topline = array_shift( $data ); - } while( $topline && $topline == '*' && !preg_match( '/\\* [0-9] FETCH.*/i', $topline )) ; + $topline = trim(array_shift( $data )); + } while( $topline && $topline[0] == '*' && !preg_match( '/\* [0-9]+ FETCH.*/i', $topline )) ; $wholemessage = implode('', $data); if (ereg('\\{([^\\}]*)\\}', $topline, $regs)) { @@ -527,14 +556,15 @@ if ($message) { /* returns a $message object for a particular entity id */ function getEntity ($message, $ent_id) { if ($message) { - if ($message->header->entity_id == $ent_id && strlen($ent_id) == strlen($message->header->entity_id)) { + if ($message->header->entity_id == $ent_id && strlen($ent_id) == strlen($message->header->entity_id)) + { return $message; } else { for ($i = 0; isset($message->entities[$i]); $i++) { $msg = getEntity ($message->entities[$i], $ent_id); if ($msg) { return $msg; - } + } } } } @@ -544,32 +574,32 @@ function getEntity ($message, $ent_id) { * figures out what entity to display and returns the $message object * for that entity. */ -function findDisplayEntity ($message, $textOnly = 1) { +function findDisplayEntity ($msg, $textOnly = 1) { global $show_html_default; $entity = 0; - if ($message) { - if ( $message->header->type0 == 'multipart' && - ( $message->header->type1 == 'alternative' || - $message->header->type1 == 'mixed' || - $message->header->type1 == 'related' ) && + if ($msg) { + if ( $msg->header->type0 == 'multipart' && + ( $msg->header->type1 == 'alternative' || + $msg->header->type1 == 'mixed' || + $msg->header->type1 == 'related' ) && $show_html_default && ! $textOnly ) { - $entity = findDisplayEntityHTML($message); + $entity = findDisplayEntityHTML($msg); } // Show text/plain or text/html -- the first one we find. if ( $entity == 0 && - $message->header->type0 == 'text' && - ( $message->header->type1 == 'plain' || - $message->header->type1 == 'html' ) && - isset($message->header->entity_id) ) { - $entity = $message->header->entity_id; + $msg->header->type0 == 'text' && + ( $msg->header->type1 == 'plain' || + $msg->header->type1 == 'html' ) && + isset($msg->header->entity_id) ) { + $entity = $msg->header->entity_id; } $i = 0; - while ($entity == 0 && isset($message->entities[$i]) ) { - $entity = findDisplayEntity($message->entities[$i], $textOnly); + while ($entity == 0 && isset($msg->entities[$i]) ) { + $entity = findDisplayEntity($msg->entities[$i], $textOnly); $i++; } } @@ -596,10 +626,96 @@ function findDisplayEntityHTML ($message) { return $entity; } } - + return 0; } +/* + * translateText + * Extracted from strings.php 23/03/2002 + */ + +function translateText(&$body, $wrap_at, $charset) { + global $where, $what; /* from searching */ + global $color; /* color theme */ + + require_once('../functions/url_parser.php'); + + $body_ary = explode("\n", $body); + $PriorQuotes = 0; + for ($i=0; $i < count($body_ary); $i++) { + $line = $body_ary[$i]; + if (strlen($line) - 2 >= $wrap_at) { + sqWordWrap($line, $wrap_at); + } + $line = charset_decode($charset, $line); + $line = str_replace("\t", ' ', $line); + + parseUrl ($line); + + $Quotes = 0; + $pos = 0; + $j = strlen( $line ); + + while ( $pos < $j ) { + if ($line[$pos] == ' ') { + $pos ++; + } else if (strpos($line, '>', $pos) === $pos) { + $pos += 4; + $Quotes ++; + } else { + break; + } + } + + if ($Quotes > 1) { + if (! isset($color[14])) { + $color[14] = '#FF0000'; + } + $line = '' . $line . ''; + } elseif ($Quotes) { + if (! isset($color[13])) { + $color[13] = '#800000'; + } + $line = '' . $line . ''; + } + + $body_ary[$i] = $line; + } + $body = '
' . implode("\n", $body_ary) . '
'; +} + +/* debugfunction for looping through entities and displaying correct entities */ +function listMyEntities ($message) { + +if ($message) { + if ($message->header->entity_id) { + echo "" . $message->header->entity_id . ' : ' . $message->header->type0 . '/' . $message->header->type1 . '
'; + } + if (!($message->header->type0 == 'message' && $message->header->type1 == 'rfc822')) { + if (isset($message->header->boundary) ) { + $ent_id = $message->header->entity_id; + $var = $message->header->boundary; + if ($var !='') + echo "$ent_id boundary = $var
"; + } + if (isset($message->header->type) ) { + $var = $message->header->type; + if ($var !='') + echo "$ent_id type = $var
"; + } + for ($i = 0; $message->entities[$i]; $i++) { + $msg = listMyEntities($message->entities[$i]); + } + + if ($msg ) return $msg; + } +} + +} + + + /* This returns a parsed string called $body. That string can then be displayed as the actual message in the HTML. It contains everything needed, including HTML Tags, Attachments at the @@ -617,19 +733,17 @@ function formatBody($imap_stream, $message, $color, $wrap_at) { $id = $message->header->id; $urlmailbox = urlencode($message->header->mailbox); - +// ListMyEntities($message); // Get the right entity and redefine message to be this entity // 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')) { $body = mime_fetch_body ($imap_stream, $id, $ent_num); $body = decodeBody($body, $body_message->header->encoding); $hookResults = do_hook("message_body", $body); $body = $hookResults[1]; - // If there are other types that shouldn't be formatted, add // them here if ($body_message->header->type1 == 'html') { @@ -687,9 +801,11 @@ function formatAttachments($message, $ent_id, $mailbox, $id) { $header = $message->header; $type0 = strtolower($header->type0); $type1 = strtolower($header->type1); - $name = decodeHeader($header->name); - - if ($type0 =='message' && $type1 = 'rfc822') { + $name = ''; + if (isset($header->name)) { + $name = decodeHeader($header->name); + } + if ($type0 =='message' && $type1 == 'rfc822') { $filename = decodeHeader($message->header->filename); if (trim($filename) == '') { @@ -870,42 +986,37 @@ function decodeBody($body, $encoding) { /* * This functions decode strings that is encoded according to * RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text). + * Patched by Christian Schmidt 23/03/2002 */ function decodeHeader ($string, $utfencode=true) { + if (is_array($string)) { + $string = implode("\n", $string); + } + $i = 0; + while (preg_match('/^(.{' . $i . '})(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=/Ui', + $string, $res)) { + $prefix = $res[1]; + // Ignore white-space between consecutive encoded-words + if (strspn($res[2], " \t") != strlen($res[2])) { + $prefix .= $res[2]; + } -if ( is_array( $string ) ) { - $string = implode("\n", $string ); -} - -if (eregi('=\\?([^?]+)\\?(q|b)\\?([^?]+)\\?=', - $string, $res)) { - if (ucfirst($res[2]) == 'B') { - $replace = base64_decode($res[3]); - } else { - $replace = str_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)) { - $replace = str_replace($res[1], strtoupper($res[1]), $replace); + if (ucfirst($res[4]) == 'B') { + $replace = base64_decode($res[5]); + } else { + $replace = str_replace('_', ' ', $res[5]); + $replace = preg_replace('/=([0-9a-f]{2})/ie', 'chr(hexdec("\1"))', + $replace); + /* Only encode into entities by default. Some places + don't need the encoding, like the compose form. */ + if ($utfencode) { + $replace = charset_decode($res[3], $replace); + } } - $replace = quoted_printable_decode($replace); - } - /* Only encode into entities by default. Some places - don't need the encoding, like the compose form. */ - if ($utfencode){ - $replace = charset_decode ($res[1], $replace); + $string = $prefix . $replace . substr($string, strlen($res[0])); + $i = strlen($prefix) + strlen($replace); } - - // 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 - $string = decodeHeader($string); -} - -return ($string); + return( $string ); } /* @@ -974,12 +1085,16 @@ function MagicHTML( $body, $id ) { $pos = $i + 1; $tag = ''; while ($body{$pos} == ' ' || $body{$pos} == "\t" || - $body{$pos} == "\n" ) { + $body{$pos} == "\n") { $pos ++; } while (strlen($tag) < 4 && $body{$pos} != ' ' && $body{$pos} != "\t" && $body{$pos} != "\n" && $pos < $j ) { + if ($body{$pos} == "<"){ + $tag = ''; + $pos++; + } $tag .= $body{$pos}; $pos ++; } @@ -1352,11 +1467,9 @@ function stripEvent( &$i, $j, &$body, $id, $base ) { /* This function trys to locate the entity_id of a specific mime element */ function find_ent_id( $id, $message ) { - $ret = ''; for ($i=0; $ret == '' && $i < count($message->entities); $i++) { - - if ( $message->entities[$i]->header->entity_id == '' ) { + if ( $message->entities[$i]->header->entity_id == '' || $message->entities[$i]->header->type ) { $ret = find_ent_id( $id, $message->entities[$i] ); } else { if ( strcasecmp( $message->entities[$i]->header->id, $id ) == 0 )