X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fmime.php;h=57ab298121fddc10171f21ccc5a026973688da7a;hb=a6c45e38b7ae30f709c314c55f9657a35dab8b10;hp=ca43a355f07ce35059f53e6d4bcb64a1a83a167b;hpb=098ea084d624846de46648afacc0564d9f2c1959;p=squirrelmail.git diff --git a/functions/mime.php b/functions/mime.php index ca43a355..57ab2981 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -34,7 +34,8 @@ function mime_structure ($bodystructure, $flags=array()) { if (!is_object($msg)) { include_once(SM_PATH . 'functions/display_messages.php'); global $color, $mailbox; - displayPageHeader( $color, urldecode($mailbox) ); + /* removed urldecode because $_GET is auto urldecoded ??? */ + displayPageHeader( $color, $mailbox ); echo "\n\n" . '
'; $errormessage = _("SquirrelMail could not decode the bodystructure of the message"); @@ -99,9 +100,9 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1) { * that it is the first one. That is usually the case anyway. */ if (!$ent_id) { - $cmd = "FETCH $id BODY[]"; + $cmd = "FETCH $id BODY[]"; } else { - $cmd = "FETCH $id BODY[$ent_id]"; + $cmd = "FETCH $id BODY[$ent_id]"; } $data = sqimap_run_command ($imap_stream, $cmd, true, $response, $message, $uid_support); @@ -115,9 +116,9 @@ function mime_fetch_body($imap_stream, $id, $ent_id=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. */ - if ($ret{0} == '<') { - $data = sqimap_run_command ($imap_stream, "FETCH $id BODY[$ent_id.MIME]", true, $response, $message, $uid_support); - } +// if ($ret{0} == '<') { +// $data = sqimap_run_command ($imap_stream, "FETCH $id BODY[$ent_id.MIME]", true, $response, $message, $uid_support); +// } } else if (ereg('"([^"]*)"', $topline, $regs)) { $ret = $regs[1]; } else { @@ -319,6 +320,7 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma */ global $startMessage, $username, $key, $imapServerAddress, $imapPort, $show_html_default, $sort, $has_unsafe_images, $passed_ent_id; + global $languages, $squirrelmail_language; if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) { $view_unsafe_images = false; @@ -331,6 +333,13 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma ($body_message->header->type0 == 'rfc822')) { $body = mime_fetch_body ($imap_stream, $id, $ent_num); $body = decodeBody($body, $body_message->header->encoding); + + if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && + function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) { + if (mb_detect_encoding($body) != 'ASCII') { + $body = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $body); + } + } $hookResults = do_hook("message_body", $body); $body = $hookResults[1]; @@ -359,24 +368,24 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma translateText($body, $wrap_at, $body_message->header->getParameter('charset')); } - $link = 'read_body.php?passed_id=' . $id . '&ent_id='.$ent_num. - '&mailbox=' . $urlmailbox .'&sort=' . $sort . - '&startMessage=' . $startMessage . '&show_more=0'; - if (isset($passed_ent_id)) { - $link .= '&passed_ent_id='.$passed_ent_id; - } + $link = 'read_body.php?passed_id=' . $id . '&ent_id='.$ent_num. + '&mailbox=' . $urlmailbox .'&sort=' . $sort . + '&startMessage=' . $startMessage . '&show_more=0'; + if (isset($passed_ent_id)) { + $link .= '&passed_ent_id='.$passed_ent_id; + } if ($view_unsafe_images) { $text = _("Hide Unsafe Images"); } else { - if (isset($has_unsafe_images) && $has_unsafe_images) { - $link .= '&view_unsafe_images=1'; - $text = _("View Unsafe Images"); - } else { - $text = ''; - } + if (isset($has_unsafe_images) && $has_unsafe_images) { + $link .= '&view_unsafe_images=1'; + $text = _("View Unsafe Images"); + } else { + $text = ''; + } } $body .= '
'.$text. - '

' . "\n"; + '

' . "\n"; } return $body; } @@ -395,22 +404,22 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { $urlMailbox = urlencode($mailbox); foreach ($att_ar as $att) { - $ent = urldecode($att->entity_id); + $ent = $att->entity_id; $header = $att->header; $type0 = strtolower($header->type0); $type1 = strtolower($header->type1); $name = ''; $links['download link']['text'] = _("download"); - $links['download link']['href'] = - "../src/download.php?absolute_dl=true&passed_id=$id&mailbox=$urlMailbox&ent_id=$ent"; + $links['download link']['href'] = SM_PATH . + "src/download.php?absolute_dl=true&passed_id=$id&mailbox=$urlMailbox&ent_id=$ent"; $ImageURL = ''; if ($type0 =='message' && $type1 == 'rfc822') { - $default_page = '../src/read_body.php'; + $default_page = SM_PATH . 'src/read_body.php'; $rfc822_header = $att->rfc822_header; $filename = $rfc822_header->subject; if (trim( $filename ) == '') { $filename = 'untitled-[' . $ent . ']' ; - } + } $from_o = $rfc822_header->from; if (is_object($from_o)) { $from_name = $from_o->getAddress(false); @@ -420,7 +429,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { $from_name = decodeHeader(($from_name)); $description = $from_name; } else { - $default_page = '../src/download.php'; + $default_page = SM_PATH . 'src/download.php'; if (is_object($header->disposition)) { $filename = $header->disposition->getProperty('filename'); if (trim($filename) == '') { @@ -432,24 +441,24 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { $filename = 'untitled-[' . $ent . ']' ; } else { $filename = 'cid: ' . $header->id; - } + } } else { - $filename = $name; + $filename = $name; } } else { $filename = $name; } } } else { - $filename = $header->getParameter('name'); - if (!trim($filename)) { - if (trim( $header->id ) == '') { - $filename = 'untitled-[' . $ent . ']' ; - } else { - $filename = 'cid: ' . $header->id; - } - } - } + $filename = $header->getParameter('name'); + if (!trim($filename)) { + if (trim( $header->id ) == '') { + $filename = 'untitled-[' . $ent . ']' ; + } else { + $filename = 'cid: ' . $header->id; + } + } + } if ($header->description) { $description = decodeHeader($header->description); } else { @@ -465,7 +474,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { } $defaultlink = $default_page . "?startMessage=$startMessage" . "&passed_id=$id&mailbox=$urlMailbox" - . '&ent_id='.$ent.$passed_ent_id_link.'&absolute_dl=true'; + . '&ent_id='.$ent.$passed_ent_id_link; if ($where && $what) { $defaultlink .= '&where='. urlencode($where).'&what='.urlencode($what); } @@ -511,7 +520,6 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { /* This function decodes the body depending on the encoding type. */ function decodeBody($body, $encoding) { - global $languages, $squirrelmail_language; global $show_html_default; $body = str_replace("\r\n", "\n", $body); @@ -529,11 +537,6 @@ function decodeBody($body, $encoding) { $body = base64_decode($body); } - if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && - function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) { - $body = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $body); - } - // All other encodings are returned raw. return $body; } @@ -548,28 +551,50 @@ function decodeHeader ($string, $utfencode=true,$htmlsave=true) { if (is_array($string)) { $string = implode("\n", $string); } - + if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) { $string = $languages[$squirrelmail_language]['XTRA_CODE']('decodeheader', $string); + // Do we need to return at this point? + // return $string; } - $i = 0; + $iLastMatch = -2; + $encoded = false; + $aString = explode(' ',$string); + $ret = ''; foreach ($aString as $chunk) { + if ($encoded && !$chunk) { + continue; + } elseif (!$chunk) { + $ret .= ' '; + continue; + } $encoded = false; - $aString[$i] = ''; - while (preg_match('/^(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=(.*)$/Ui',$chunk,$res)) { - $aString[$i] .= $res[1]; + /* if encoded words are not separated by a linear-space-white we still catch them */ + $j = $i-1; + if ($chunk{0} === '=') { /* performance, saves an unnessecarry preg call */ + while ($match = preg_match('/^(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=(.*)$/Ui',$chunk,$res)) { + /* if the last chunk isn't an encoded string then put back the space, otherwise don't */ + if ($iLastMatch !== $j) { + if ($htmlsave) { + $ret .= ' '; + } else { + $ret .= ' '; + } + } + $iLastMatch = $i; + $j = $i; + $ret .= $res[1]; $encoding = ucfirst($res[3]); switch ($encoding) { case 'B': $replace = base64_decode($res[4]); - $aString[$i] .= charset_decode($res[2],$replace); + $ret .= charset_decode($res[2],$replace); break; case 'Q': - $replace = str_replace('_', ' ', $res[4]); $replace = preg_replace('/=([0-9a-f]{2})/ie', 'chr(hexdec("\1"))', $replace); @@ -580,29 +605,43 @@ function decodeHeader ($string, $utfencode=true,$htmlsave=true) { $replace = charset_decode($res[2], $replace); } else { if ($htmlsave) { - $replace = htmlspecialchars($res[4]); + $replace = htmlspecialchars($replace); } } - $aString[$i] .= $replace; + $ret .= $replace; break; default: break; } $chunk = $res[5]; $encoded = true; - } + } + } + if (!$encoded) { + if ($htmlsave) { + $ret .= ' '; + } else { + $ret .= ' '; + } + } + if (!$encoded && $htmlsave) { - $aString[$i] = htmlspecialchars($chunk); + $ret .= htmlspecialchars($chunk); } else { - $aString[$i] .= $chunk; + $ret .= $chunk; } ++$i; } - if (!$htmlsave) { - return implode(' ',$aString); - } else { - return implode(' ',$aString); + /* remove the first added space */ + if ($ret) { + if ($htmlsave) { + $ret = substr($ret,6); + } else { + $ret = substr($ret,1); + } } + + return $ret; } /* @@ -617,81 +656,114 @@ function encodeHeader ($string) { function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) { return $languages[$squirrelmail_language]['XTRA_CODE']('encodeheader', $string); } + if (strtolower($default_charset) == 'iso-8859-1') { + $string = str_replace("\240",' ',$string); + } // Encode only if the string contains 8-bit characters or =? $j = strlen($string); - $l = strstr($string, '=?'); // Must be encoded ? $max_l = 75 - strlen($default_charset) - 7; $aRet = array(); $ret = ''; - $cur_l = 0; + $iEncStart = $enc_init = false; + $cur_l = $iOffset = 0; for($i = 0; $i < $j; ++$i) { - switch($string{$i}) { - case '=': - $cur_l+=3; - if ($cur_l > $max_l) { - $aRet[] = "=?$default_charset?Q?$ret?="; - $cur_l = 3; - $ret = ''; - } - $ret .= '=3D'; - break; - case '?': - $cur_l+=3; + switch($string{$i}) + { + case '=': + case '<': + case '>': + case ',': + case '?': + case '_': + if ($iEncStart === false) { + $iEncStart = $i; + } + $cur_l+=3; + if ($cur_l > ($max_l-2)) { + /* if there is an stringpart that doesn't need encoding, add it */ + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); + $aRet[] = "=?$default_charset?Q?$ret?="; + $iOffset = $i; + $cur_l = 0; + $ret = ''; + $iEncStart = false; + } else { + $ret .= sprintf("=%02X",ord($string{$i})); + } + break; + case '(': + case ')': + if ($iEncStart !== false) { + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); + $aRet[] = "=?$default_charset?Q?$ret?="; + $iOffset = $i; + $cur_l = 0; + $ret = ''; + $iEncStart = false; + } + break; + case ' ': + if ($iEncStart !== false) { + $cur_l++; if ($cur_l > $max_l) { + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); $aRet[] = "=?$default_charset?Q?$ret?="; - $cur_l = 3; + $iOffset = $i; + $cur_l = 0; $ret = ''; + $iEncStart = false; + } else { + $ret .= '_'; } - $ret .= '=3F'; - break; - case '_': - $cur_l+=3; - if ($cur_l > $max_l) { - $aRet[] = "=?$default_charset?Q?$ret?="; + } + break; + default: + $k = ord($string{$i}); + if ($k > 126) { + if ($iEncStart === false) { + $iEncStart = $i; + } + $cur_l += 3; + /* first we add the encoded string that reached it's max size */ + if ($cur_l > ($max_l-2)) { + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); + $aRet[] = "=?$default_charset?Q?$ret?= "; /* the next part is also encoded => separate by space */ $cur_l = 3; $ret = ''; - } - $ret .= '=5F'; - break; - case ' ': - $cur_l++; - if ($cur_l > $max_l) { - $aRet[] = "=?$default_charset?Q?$ret?="; - $cur_l = 1; - $ret = ''; - } - $ret .= '_'; - break; - default: - $k = ord($string{$i}); - if ($k > 126) { - $s = sprintf("=%02X", $k); - $cur_l += strlen($s); - if ($cur_l > $max_l) { - $aRet[] = "=?$default_charset?Q?$ret?="; - $cur_l = strlen($s); - $ret = ''; - } - $ret .= $s; - $l = TRUE; - } else { + $iOffset = $i; + $iEncStart = $i; + } + $enc_init = true; + $ret .= sprintf("=%02X", $k); + } else { + if ($iEncStart !== false) { $cur_l++; if ($cur_l > $max_l) { + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); $aRet[] = "=?$default_charset?Q?$ret?="; - $cur_l = 1; + $iEncStart = false; + $iOffset = $i; + $cur_l = 0; $ret = ''; - } - $ret .= $string{$i}; + } else { + $ret .= $string{$i}; + } } - break; + } + break; } } - if ($l) { - $string = implode('',$aRet) . "=?$default_charset?Q?$ret?="; + if ($enc_init) { + if ($iEncStart !== false) { + $aRet[] = substr($string,$iOffset,$iEncStart-$iOffset); + $aRet[] = "=?$default_charset?Q?$ret?="; + } else { + $aRet[] = substr($string,$iOffset); + } + $string = implode('',$aRet); } - return $string; } @@ -1305,9 +1377,9 @@ function sq_fixstyle($message, $id, $content){ * Fix stupid css declarations which lead to vulnerabilities * in IE. */ - $match = Array('/expression/si', - '/behaviou*r/si', - '/binding/si'); + $match = Array('/expression/i', + '/behaviou*r/i', + '/binding/i'); $replace = Array('idiocy', 'idiocy', 'idiocy'); $content = preg_replace($match, $replace, $content); return $content; @@ -1334,7 +1406,7 @@ function sq_cid2http($message, $id, $cidurl, $mailbox){ unsave link image */ $httpurl = ''; if ($linkurl) { - $httpurl = $quotchar . '../src/download.php?absolute_dl=true&' . + $httpurl = $quotchar . SM_PATH . 'src/download.php?absolute_dl=true&' . "passed_id=$id&mailbox=" . urlencode($mailbox) . '&ent_id=' . $linkurl . $quotchar; } @@ -1594,10 +1666,11 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX') { $rm_attnames = Array( "/.*/" => Array( - "/target/si", - "/^on.*/si", - "/^dynsrc/si", - "/^data.*/si" + "/target/i", + "/^on.*/i", + "/^dynsrc/i", + "/^data.*/i", + "/^lowsrc.*/i" ) ); @@ -1635,12 +1708,12 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX') { "\\1#\\2" ) ), - "/^style/si" => + "/^style/i" => Array( Array( - "/expression/si", - "/binding/si", - "/behaviou*r/si", + "/expression/i", + "/binding/i", + "/behaviou*r/i", "|url\(([\'\"])\s*\.\./.*([\'\"])\)|si", "/url\(([\'\"])\s*\S+script\s*:.*([\'\"])\)/si", "/url\(([\'\"])\s*mocha\s*:.*([\'\"])\)/si", @@ -1670,14 +1743,14 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX') { '/^([\'\"])\s*https*:.*([\'\"])/si'); array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1], "\\1$secremoveimg\\2"); - array_push($bad_attvals{'/.*/'}{'/^style/si'}[0], + array_push($bad_attvals{'/.*/'}{'/^style/i'}[0], '/url\(([\'\"])\s*https*:.*([\'\"])\)/si'); - array_push($bad_attvals{'/.*/'}{'/^style/si'}[1], + array_push($bad_attvals{'/.*/'}{'/^style/i'}[1], "url(\\1$secremoveimg\\2)"); } $add_attr_to_tag = Array( - "/^a$/si" => Array('target'=>'"_new"') + "/^a$/i" => Array('target'=>'"_new"') ); $trusted = sq_sanitize($body, $tag_list, @@ -1691,7 +1764,7 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX') { $id, $mailbox ); - if (preg_match("|$secremoveimg|si", $trusted)){ + if (preg_match("|$secremoveimg|i", $trusted)){ $has_unsafe_images = true; } return $trusted;