- $body_message->header->getParameter('charset'));
+ $body_message->header->getParameter('charset'));
+ } elseif ($use_iframe && ! $clean) {
+ // $clean is used to remove iframe in printable view.
+
+ /**
+ * If we don't add html message between iframe tags,
+ * we must detect unsafe images and modify $has_unsafe_images.
+ */
+ $html_body = magicHTML($body, $id, $message, $mailbox);
+
+ // creating iframe url
+ $iframeurl=sqm_baseuri().'src/view_html.php?'
+ . 'mailbox=' . $urlmailbox
+ . '&passed_id=' . $id
+ . '&ent_id=' . $ent_num
+ . '&view_unsafe_images=' . (int) $view_unsafe_images;
+
+ // adding warning message
+ $body = html_tag('div',_("Viewing HTML formatted email"),'center');
+
+ /**
+ * height can't be set to 100%, because it does not work as expected when
+ * iframe is inside the table. Browsers do not create full height objects
+ * even when iframe is not nested. Maybe there is some way to get full size
+ * with CSS. Tested in firefox 1.02 and opera 7.53
+ *
+ * width="100%" does not work as expected, when table width is not set (automatic)
+ *
+ * tokul: I think <iframe> are safer sandbox than <object>. Objects might
+ * need special handling for IE and IE6SP2.
+ */
+ $body.= "<div><iframe name=\"message_frame\" width=\"100%\" height=\"$iframe_height\" src=\"$iframeurl\""
+ .' frameborder="1" marginwidth="0" marginheight="0" scrolling="auto">' . "\n";
+
+ // Message for browsers without iframe support
+ //$body.= _("Your browser does not support inline frames.
+ // You can view HTML formated message by following below link.");
+ //$body.= "<br /><a href=\"$iframeurl\">"._("View HTML Message")."</a>";
+
+ // if browser can't render iframe, it renders html message.
+ $body.= $html_body;
+
+ // close iframe
+ $body.="</iframe></div>\n";
- /**
- * See if we have to run the checks first. All entities must start
- * with "&".
- */
- if (strpos($attvalue, '&') === false){
- return $attvalue;
- }
- /**
- * Check named entities first.
- */
- $trans = get_html_translation_table(HTML_ENTITIES);
- /**
- * Leave " in, as it can mess us up.
- */
- $trans = array_flip($trans);
- unset($trans{'"'});
- while (list($ent, $val) = each($trans)){
- $attvalue = preg_replace('/' . $ent . '*/si', $val, $attvalue);
- }
- /**
- * Now translate numbered entities from 1 to 255 if needed.
- */
- if (strpos($attvalue, '#') !== false){
- $omit = Array(34, 39);
- for ($asc = 256; $asc >= 0; $asc--){
- if (!in_array($asc, $omit)){
- $chr = chr($asc);
- $octrule = '/\�*' . $asc . ';*/si';
- $hexrule = '/\�*' . dechex($asc) . ';*/si';
- $attvalue = preg_replace($octrule, $chr, $attvalue);
- $attvalue = preg_replace($hexrule, $chr, $attvalue);
+ $ret_match = false;
+ preg_match_all($regex, $attvalue, $matches);
+ if (is_array($matches) && sizeof($matches[0]) > 0){
+ $repl = Array();
+ for ($i = 0; $i < sizeof($matches[0]); $i++){
+ $numval = $matches[1][$i];
+ if ($hex){
+ $numval = hexdec($numval);
- * Fix url('blah') declarations.
- */
- $content = preg_replace("|url\s*\(\s*([\'\"])\s*\S+script\s*:.*?([\'\"])\s*\)|si",
- "url(\\1$secremoveimg\\2)", $content);
- /**
- * Fix url('https*://.*) declarations but only if $view_unsafe_images
- * is false.
- */
- if (!$view_unsafe_images){
- $content = preg_replace("|url\s*\(\s*([\'\"])\s*https*:.*?([\'\"])\s*\)|si",
- "url(\\1$secremoveimg\\2)", $content);
+ * Fix url('blah') declarations.
+ */
+ // $content = preg_replace("|url\s*\(\s*([\'\"])\s*\S+script\s*:.*?([\'\"])\s*\)|si",
+ // "url(\\1$secremoveimg\\2)", $content);
+ // remove NUL
+ $content = str_replace("\0", "", $content);
+ // NB I insert NUL characters to keep to avoid an infinite loop. They are removed after the loop.
+ while (preg_match("/url\s*\(\s*[\'\"]?([^:]+):(.*)?[\'\"]?\s*\)/si", $content, $matches)) {
+ $sProto = strtolower($matches[1]);
+ switch ($sProto) {
+ /**
+ * Fix url('https*://.*) declarations but only if $view_unsafe_images
+ * is false.
+ */
+ case 'https':
+ case 'http':
+ if (!$view_unsafe_images){
+ $sExpr = "/url\s*\(\s*([\'\"])\s*$sProto*:.*?([\'\"])\s*\)/si";
+ $content = preg_replace($sExpr, "u\0r\0l(\\1$secremoveimg\\2)", $content);
+ }
+ break;
+ /**
+ * Fix urls that refer to cid:
+ */
+ case 'cid':
+ $cidurl = 'cid:'. $matches[2];
+ $httpurl = sq_cid2http($message, $id, $cidurl, $mailbox);
+ $content = preg_replace("|url\s*\(\s*$cidurl\s*\)|si",
+ "u\0r\0l($httpurl)", $content);
+ break;
+ default:
+ /**
+ * replace url with protocol other then the white list
+ * http,https and cid by an empty string.
+ */
+ $content = preg_replace("/url\s*\(\s*[\'\"]?([^:]+):(.*)?[\'\"]?\s*\)/si",
+ "", $content);
+ break;
+ }
+ break;
+
+ // we want to parse mailto's in HTML output, change to SM compose links
+ // this is a modified version of code from url_parser.php... but Marc is
+ // right: we need a better filtering implementation; adding this randomly
+ // here is not a great solution
+ //
+ if ($take_mailto_links) {
+ // parseUrl($trusted); // this even parses URLs inside of tags... too aggressive
+ global $MailTo_PReg_Match;
+ $MailTo_PReg_Match = '/mailto:' . substr($MailTo_PReg_Match, 1);
+ if ((preg_match_all($MailTo_PReg_Match, $trusted, $regs)) && ($regs[0][0] != '')) {
+ foreach ($regs[0] as $i => $mailto_before) {
+ $mailto_params = $regs[10][$i];
+ // get rid of any tailing quote since we have to add send_to to the end
+ //
+ if (substr($mailto_before, strlen($mailto_before) - 1) == '"')
+ $mailto_before = substr($mailto_before, 0, strlen($mailto_before) - 1);
+ if (substr($mailto_params, strlen($mailto_params) - 1) == '"')
+ $mailto_params = substr($mailto_params, 0, strlen($mailto_params) - 1);
+
+ if ($regs[1][$i]) { //if there is an email addr before '?', we need to merge it with the params
+ $to = 'to=' . $regs[1][$i];
+ if (strpos($mailto_params, 'to=') > -1) //already a 'to='
+ $mailto_params = str_replace('to=', $to . '%2C%20', $mailto_params);
+ else {
+ if ($mailto_params) //already some params, append to them
+ $mailto_params .= '&' . $to;
+ else
+ $mailto_params .= '?' . $to;
+ }
+ }
+
+ $url_str = preg_replace(array('/to=/i', '/(?<!b)cc=/i', '/bcc=/i'), array('send_to=', 'send_to_cc=', 'send_to_bcc='), $mailto_params);
+
+ // we'll already have target=_blank, no need to allow comp_in_new
+ // here (which would be a lot more work anyway)
+ //
+ global $compose_new_win;
+ $temp_comp_in_new = $compose_new_win;
+ $compose_new_win = 0;
+ $comp_uri = makeComposeLink('src/compose.php' . $url_str, $mailto_before);
+ $compose_new_win = $temp_comp_in_new;
+
+ // remove <a href=" and anything after the next quote (we only
+ // need the uri, not the link HTML) in compose uri
+ //
+ $comp_uri = substr($comp_uri, 9);
+ $comp_uri = substr($comp_uri, 0, strpos($comp_uri, '"', 1));
+ $trusted = str_replace($mailto_before, $comp_uri, $trusted);
+ }
+ }
+ }
+
- function SendDownloadHeaders($type0, $type1, $filename, $force, $filesize=0) {
- global $languages, $squirrelmail_language;
- $isIE = $isIE6 = 0;
-
- sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER);
-
- if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !== false &&
- strstr($HTTP_USER_AGENT, 'Opera') === false) {
- $isIE = 1;
- }
-
- if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !== false &&
- strstr($HTTP_USER_AGENT, 'Opera') === false) {
- $isIE6 = 1;
- }
-
- if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
- function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_downloadfilename')) {
- $filename =
- call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_downloadfilename', $filename, $HTTP_USER_AGENT);
- } else {
- $filename = ereg_replace('[\\/:\*\?"<>\|;]', '_', str_replace(' ', ' ', $filename));
- }
-
- // A Pox on Microsoft and it's Internet Explorer!
- //
- // IE has lots of bugs with file downloads.
- // It also has problems with SSL. Both of these cause problems
- // for us in this function.
- //
- // See this article on Cache Control headers and SSL
- // http://support.microsoft.com/default.aspx?scid=kb;en-us;323308
- //
- // The best thing you can do for IE is to upgrade to the latest
- // version
- //set all the Cache Control Headers for IE
- if ($isIE) {
- $filename=rawurlencode($filename);
- header ("Pragma: public");
- header ("Cache-Control: no-store, max-age=0, no-cache, must-revalidate"); # HTTP/1.1
- header ("Cache-Control: post-check=0, pre-check=0", false);
- header ("Cache-control: private");
-
- //set the inline header for IE, we'll add the attachment header later if we need it
- header ("Content-Disposition: inline; filename=$filename");
- }
-
- if (!$force) {
- // Try to show in browser window
- header ("Content-Disposition: inline; filename=\"$filename\"");
- header ("Content-Type: $type0/$type1; name=\"$filename\"");
- } else {
- // Try to pop up the "save as" box
-
- // IE makes this hard. It pops up 2 save boxes, or none.
- // http://support.microsoft.com/support/kb/articles/Q238/5/88.ASP
- // http://support.microsoft.com/default.aspx?scid=kb;EN-US;260519
- // But, according to Microsoft, it is "RFC compliant but doesn't
- // take into account some deviations that allowed within the
- // specification." Doesn't that mean RFC non-compliant?
- // http://support.microsoft.com/support/kb/articles/Q258/4/52.ASP
-
- // all browsers need the application/octet-stream header for this
- header ("Content-Type: application/octet-stream; name=\"$filename\"");
-
- // http://support.microsoft.com/support/kb/articles/Q182/3/15.asp
- // Do not have quotes around filename, but that applied to
- // "attachment"... does it apply to inline too?
- header ("Content-Disposition: attachment; filename=\"$filename\"");
-
- if ($isIE && !$isIE6) {
- // This combination seems to work mostly. IE 5.5 SP 1 has
- // known issues (see the Microsoft Knowledge Base)
-
- // This works for most types, but doesn't work with Word files
- header ("Content-Type: application/download; name=\"$filename\"");
-
- // These are spares, just in case. :-)
- //header("Content-Type: $type0/$type1; name=\"$filename\"");
- //header("Content-Type: application/x-msdownload; name=\"$filename\"");
- //header("Content-Type: application/octet-stream; name=\"$filename\"");
- } else {
- // another application/octet-stream forces download for Netscape
- header ("Content-Type: application/octet-stream; name=\"$filename\"");
- }
- }
-
- //send the content-length header if the calling function provides it
- if ($filesize > 0) {
- header("Content-Length: $filesize");
- }
+function SendDownloadHeaders($type0, $type1, $filename, $force, $filesize=0) {
+ global $languages, $squirrelmail_language;
+ $isIE = $isIE6 = 0;
+
+ sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER);
+
+ if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !== false &&
+ strstr($HTTP_USER_AGENT, 'Opera') === false) {
+ $isIE = 1;
+ }
+
+ if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !== false &&
+ strstr($HTTP_USER_AGENT, 'Opera') === false) {
+ $isIE6 = 1;
+ }
+
+ if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
+ function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_downloadfilename')) {
+ $filename =
+ call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_downloadfilename', $filename, $HTTP_USER_AGENT);
+ } else {
+ $filename = ereg_replace('[\\/:\*\?"<>\|;]', '_', str_replace(' ', ' ', $filename));
+ }
+
+ // A Pox on Microsoft and it's Internet Explorer!
+ //
+ // IE has lots of bugs with file downloads.
+ // It also has problems with SSL. Both of these cause problems
+ // for us in this function.
+ //
+ // See this article on Cache Control headers and SSL
+ // http://support.microsoft.com/default.aspx?scid=kb;en-us;323308
+ //
+ // The best thing you can do for IE is to upgrade to the latest
+ // version
+ //set all the Cache Control Headers for IE
+ if ($isIE) {
+ $filename=rawurlencode($filename);
+ header ("Pragma: public");
+ header ("Cache-Control: no-store, max-age=0, no-cache, must-revalidate"); // HTTP/1.1
+ header ("Cache-Control: post-check=0, pre-check=0", false);
+ header ("Cache-Control: private");
+
+ //set the inline header for IE, we'll add the attachment header later if we need it
+ header ("Content-Disposition: inline; filename=$filename");
+ }
+
+ if (!$force) {
+ // Try to show in browser window
+ header ("Content-Disposition: inline; filename=\"$filename\"");
+ header ("Content-Type: $type0/$type1; name=\"$filename\"");
+ } else {
+ // Try to pop up the "save as" box
+
+ // IE makes this hard. It pops up 2 save boxes, or none.
+ // http://support.microsoft.com/support/kb/articles/Q238/5/88.ASP
+ // http://support.microsoft.com/default.aspx?scid=kb;EN-US;260519
+ // But, according to Microsoft, it is "RFC compliant but doesn't
+ // take into account some deviations that allowed within the
+ // specification." Doesn't that mean RFC non-compliant?
+ // http://support.microsoft.com/support/kb/articles/Q258/4/52.ASP
+
+ // all browsers need the application/octet-stream header for this
+ header ("Content-Type: application/octet-stream; name=\"$filename\"");
+
+ // http://support.microsoft.com/support/kb/articles/Q182/3/15.asp
+ // Do not have quotes around filename, but that applied to
+ // "attachment"... does it apply to inline too?
+ header ("Content-Disposition: attachment; filename=\"$filename\"");
+
+ if ($isIE && !$isIE6) {
+ // This combination seems to work mostly. IE 5.5 SP 1 has
+ // known issues (see the Microsoft Knowledge Base)
+
+ // This works for most types, but doesn't work with Word files
+ header ("Content-Type: application/download; name=\"$filename\"");
+
+ // These are spares, just in case. :-)
+ //header("Content-Type: $type0/$type1; name=\"$filename\"");
+ //header("Content-Type: application/x-msdownload; name=\"$filename\"");
+ //header("Content-Type: application/octet-stream; name=\"$filename\"");
+ } else {
+ // another application/octet-stream forces download for Netscape
+ header ("Content-Type: application/octet-stream; name=\"$filename\"");
+ }
+ }
+
+ //send the content-length header if the calling function provides it
+ if ($filesize > 0) {
+ header("Content-Length: $filesize");
+ }