* This contains the functions necessary to detect and decode MIME
* messages.
*
- * @copyright 1999-2012 The SquirrelMail Project Team
+ * @copyright 1999-2019 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
* @package squirrelmail
displayPageHeader( $color, $mailbox );
$errormessage = _("SquirrelMail could not decode the bodystructure of the message");
$errormessage .= '<br />'._("The bodystructure provided by your IMAP server:").'<br /><br />';
- $errormessage .= '<pre>' . htmlspecialchars($read) . '</pre>';
+ $errormessage .= '<pre>' . sm_encode_html_special_chars($read) . '</pre>';
plain_error_message( $errormessage );
echo '</body></html>';
exit;
* @param integer $id message id
*/
function buildAttachmentArray($message, $exclude_id, $mailbox, $id) {
- global $where, $what, $startMessage, $color, $passed_ent_id, $base_uri;
+ global $where, $what, $startMessage, $color, $passed_ent_id,
+ $base_uri, $block_svg_download;
$att_ar = $message->getAttachments($exclude_id);
$urlMailbox = urlencode($mailbox);
$header = $att->header;
$type0 = strtolower($header->type0);
$type1 = strtolower($header->type1);
+ if ($block_svg_download && strpos($type1, 'svg') === 0)
+ continue;
+
$name = '';
$links = array();
$links['download link']['text'] = _("Download");
$this_attachment['DownloadHREF'] = $links['download link']['href'];
$this_attachment['ViewHREF'] = isset($links['attachment_common']) ? $links['attachment_common']['href'] : '';
$this_attachment['Size'] = $header->size;
- $this_attachment['ContentType'] = htmlspecialchars($type0 .'/'. $type1);
+ $this_attachment['ContentType'] = sm_encode_html_special_chars($type0 .'/'. $type1);
$this_attachment['OtherLinks'] = array();
foreach ($links as $val) {
if ($val['text']==_("Download") || $val['text'] == _("View"))
* @return string decoded header string
*/
function decodeHeader ($string, $utfencode=true,$htmlsafe=true,$decide=false) {
- global $languages, $squirrelmail_language,$default_charset;
+ global $languages, $squirrelmail_language,$default_charset, $fix_broken_base64_encoded_messages;
if (is_array($string)) {
$string = implode("\n", $string);
}
$iLastMatch = -2;
$encoded = true;
+// FIXME: spaces are allowed inside quoted-printable encoding, but the following line will bust up any such encoded strings
$aString = explode(' ',$string);
$ret = '';
foreach ($aString as $chunk) {
$iLastMatch = $i;
$j = $i;
if ($htmlsafe) {
- $ret .= htmlspecialchars($res[1]);
+ $ret .= sm_encode_html_special_chars($res[1]);
} else {
$ret .= $res[1];
}
switch ($encoding)
{
case 'B':
+ // fix broken base64-encoded strings (remove end = padding,
+ // change any = to + in middle of string, add padding back
+ // to the end)
+ if ($fix_broken_base64_encoded_messages) {
+ $encoded_string_minus_padding = strtr(rtrim($res[4], '='), '=', '+');
+ $res[4] = str_pad($encoded_string_minus_padding, strlen($res[4]), '=');
+ }
$replace = base64_decode($res[4]);
if ($utfencode) {
if ($can_be_encoded) {
}
} else {
if ($htmlsafe) {
- $replace = htmlspecialchars($replace);
+ $replace = sm_encode_html_special_chars($replace);
}
$ret.= $replace;
}
break;
case 'Q':
$replace = str_replace('_', ' ', $res[4]);
- $replace = preg_replace('/=([0-9a-f]{2})/ie', 'chr(hexdec("\1"))',
+ $replace = preg_replace_callback('/=([0-9a-f]{2})/i',
+ create_function ('$matches', 'return chr(hexdec($matches[1]));'),
$replace);
if ($utfencode) {
if ($can_be_encoded) {
}
} else {
if ($htmlsafe) {
- $replace = htmlspecialchars($replace);
+ $replace = sm_encode_html_special_chars($replace);
}
}
$ret .= $replace;
}
if (!$encoded && $htmlsafe) {
- $ret .= htmlspecialchars($chunk);
+ $ret .= sm_encode_html_special_chars($chunk);
} else {
$ret .= $chunk;
}
/**
* Use white list based filtering on attributes which can contain url's
*/
- else if ($attname == 'href' || $attname == 'src' || $attname == 'background') {
+ else if ($attname == 'href' || $attname == 'xlink:href' || $attname == 'src'
+ || $attname == 'poster' || $attname == 'formaction'
+ || $attname == 'background' || $attname == 'action') {
sq_fix_url($attname, $attvalue, $message, $id, $mailbox);
$attary{$attname} = $attvalue;
}
// images off by default.
sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE);
- $secremoveimg = '../images/' . _("sec_remove_eng.png");
+ global $use_transparent_security_image;
+ if ($use_transparent_security_image) $secremoveimg = '../images/spacer.png';
+ else $secremoveimg = '../images/' . _("sec_remove_eng.png");
/**
* Replace empty src tags with the blank image. src is only used
* and change it to .bodyclass so we can just assign it to a <div>
*/
$content = preg_replace("|body(\s*\{.*?\})|si", ".bodyclass\\1", $content);
- $secremoveimg = '../images/' . _("sec_remove_eng.png");
+
+ global $use_transparent_security_image;
+ if ($use_transparent_security_image) $secremoveimg = '../images/spacer.png';
+ else $secremoveimg = '../images/' . _("sec_remove_eng.png");
+
/**
* Fix url('blah') declarations.
*/
* be set to relative and move itself anywhere it wants to,
* displaying content in areas it shouldn't be allowed to touch.
*/
- $match = Array('/\/\*.*\*\//',
+ $match = Array('/\/\*.*\*\//', // removes /* blah blah */
'/expression/i',
'/behaviou*r/i',
'/binding/i',
// require_once(SM_PATH . 'functions/url_parser.php'); // for $MailTo_PReg_Match
global $attachment_common_show_images, $view_unsafe_images,
- $has_unsafe_images;
+ $has_unsafe_images, $block_svg_display;
/**
* Don't display attached images in HTML mode.
*
$attachment_common_show_images = false;
$tag_list = Array(
false,
- "object",
"meta",
"html",
"head",
"frame",
"iframe",
"plaintext",
- "marquee"
+ "marquee",
);
$rm_tags_with_content = Array(
"script",
+ "object",
"applet",
"embed",
"title",
"frameset",
"xmp",
- "xml"
+ "xml",
);
+ if ($block_svg_display)
+ $rm_tags_with_content[] = 'svg';
$self_closing_tags = Array(
"img",
"br",
"hr",
"input",
- "outbind"
+ "outbind",
);
$force_tag_closing = true;
"/^on.*/i",
"/^dynsrc/i",
"/^data.*/i",
- "/^lowsrc.*/i"
+ "/^lowsrc.*/i",
)
);
- $secremoveimg = "../images/" . _("sec_remove_eng.png");
+ global $use_transparent_security_image;
+ if ($use_transparent_security_image) $secremoveimg = '../images/spacer.png';
+ else $secremoveimg = '../images/' . _("sec_remove_eng.png");
+
$bad_attvals = Array(
"/.*/" =>
Array(
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) ;
+ // some mailers (Microsoft, surprise surprise) produce mailto strings without being
+ // inside an anchor (link) tag, so we have to make sure the regex looks for the
+ // quote before mailto, and we'll also try to convert the non-links back into links
+ $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];
+ $mailto_params = $regs[11][$i];
+
+ // get rid of any leading quote we may have captured but don't care about
+ //
+ $mailto_before = ltrim($mailto_before, '"\'');
+
// 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);
+ $mailto_before = rtrim($mailto_before, '"\'');
+ $mailto_params = rtrim($mailto_params, '"\'');
- 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 ($regs[2][$i]) { //if there is an email addr before '?', we need to merge it with the params
+ $to = 'to=' . $regs[2][$i];
if (strpos($mailto_params, 'to=') > -1) //already a 'to='
$mailto_params = str_replace('to=', $to . '%2C%20', $mailto_params);
else {
// 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));
+ // but only do this if the original mailto was in a real anchor tag
+ //
+ if (!empty($regs[1][$i])) {
+ $comp_uri = substr($comp_uri, 9);
+ $comp_uri = substr($comp_uri, 0, strpos($comp_uri, '"', 1));
+ }
$trusted = str_replace($mailto_before, $comp_uri, $trusted);
}
}
$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);
+ // does nothing - see: https://blogs.msdn.microsoft.com/ieinternals/2009/07/20/internet-explorers-cache-control-extensions/
+ // 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