// }
} else if (ereg('"([^"]*)"', $topline, $regs)) {
$ret = $regs[1];
+ } else if ((stristr($topline, 'nil') !== false) && (empty($wholemessage))) {
+ $ret = $wholemessage;
} else {
global $where, $what, $mailbox, $passed_id, $startMessage;
$par = 'mailbox=' . urlencode($mailbox) . '&passed_id=' . $passed_id;
* @param string $ent_num (since 1.3.0) message part id
* @param integer $id (since 1.3.0) message id
* @param string $mailbox (since 1.3.0) imap folder name
- * @param boolean $clean (since 1.5.1) Do not output stuff that's irrelevant for the printable version.
* @return string html formated message text
*/
-function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $mailbox='INBOX', $clean=FALSE) {
+function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $mailbox='INBOX') {
/* This if statement checks for the entity to show as the
* primary message. To add more of them, just put them in the
* order that is their priority.
$show_html_default, $sort, $has_unsafe_images, $passed_ent_id,
$use_iframe, $iframe_height, $download_and_unsafe_link,
$download_href, $unsafe_image_toggle_href, $unsafe_image_toggle_text,
- $oTemplate;
-
- $nbsp = $oTemplate->fetch('non_breaking_space.tpl');
+ $oTemplate, $nbsp;
// workaround for not updated config.php
if (! isset($use_iframe)) $use_iframe = false;
- if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) {
- $view_unsafe_images = false;
- }
+ // If there's no "view_unsafe_images" variable in the URL, turn unsafe
+ // images off by default.
+ sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE);
$body = '';
$urlmailbox = urlencode($mailbox);
$body = trim($body);
translateText($body, $wrap_at,
$body_message->header->getParameter('charset'));
- } elseif ($use_iframe && ! $clean) {
- // $clean is used to remove iframe in printable view.
-
+ } elseif ($use_iframe) {
/**
* If we don't add html message between iframe tags,
* we must detect unsafe images and modify $has_unsafe_images.
global $oTemplate;
$oTemplate->assign('iframe_url', $iframeurl);
+ $oTemplate->assign('iframe_height', $iframe_height);
$oTemplate->assign('html_body', $html_body);
$body = $oTemplate->fetch('read_html_iframe.tpl');
$body_message->header->getParameter('charset'));
}
- // if this is the clean display (i.e. printer friendly), stop here.
- if ( $clean ) {
- return $body;
- }
+ /*
+ * Previously the links for downloading and unsafe images were printed
+ * under the mail. By putting the links in a global variable we can
+ * print it in the toolbar where it belongs. Since the original code was
+ * in this place it's left here. It might be possible to move it to some
+ * other place if that makes sense. The possibility to do so has not
+ * been evaluated yet.
+ */
+ // Initialize the global variable to an empty string.
+ // FIXME: To have $download_and_unsafe_link as a global variable might not be needed since the use of separate variables ($download_href, $unsafe_image_toggle_href, and $unsafe_image_toggle_text) for the templates was introduced.
$download_and_unsafe_link = '';
+ // Prepare and build a link for downloading the mail.
$link = 'passed_id=' . $id . '&ent_id='.$ent_num.
'&mailbox=' . $urlmailbox .'&sort=' . $sort .
'&startMessage=' . $startMessage . '&show_more=0';
$link .= '&passed_ent_id='.$passed_ent_id;
}
$download_href = SM_PATH . 'src/download.php?absolute_dl=true&' . $link;
+
+ // Always add the link for downloading the mail as a file to the global
+ // variable.
$download_and_unsafe_link .= "$nbsp|$nbsp"
. create_hyperlink($download_href, _("Download this as a file"));
+
+ // Find out the right text to use in the link depending on the
+ // circumstances. If the unsafe images are displayed the link should
+ // hide them, if they aren't displayed the link should only appear if
+ // the mail really contains unsafe images.
if ($view_unsafe_images) {
$text = _("Hide Unsafe Images");
} else {
$text = '';
}
}
+
+ // Only create a link for unsafe images if there's need for one. If so:
+ // add it to the global variable.
if($text != '') {
$unsafe_image_toggle_href = SM_PATH . 'src/read_body.php?'.$link;
$unsafe_image_toggle_text = $text;
}
/**
- * Generate attachments array for passing to templates. Separated from
- * formatAttachments() below so that the same array can be given to the
- * print-friendly version.
+ * Generate attachments array for passing to templates.
*
* @since 1.5.2
* @param object $message SquirrelMail message object
* for a more generic type. Finally, a hook for ALL attachment
* types is run as well.
*/
+ // First remember the default link.
+ $defaultlink_orig = $defaultlink;
+
/* The API for this hook has changed as of 1.5.2 so that all plugin
arguments are passed in an array instead of each their own plugin
argument, and arguments are passed by reference, so instead of
returning any changes, changes should simply be made to the original
arguments themselves. */
- do_hook("attachment $type0/$type1", $temp=array(&$links,
- &$startMessage, &$id, &$urlMailbox, &$ent, &$defaultlink,
- &$display_filename, &$where, &$what));
- if(count($links) <= 1) {
+ $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent,
+ &$defaultlink, &$display_filename, &$where, &$what);
+ do_hook("attachment $type0/$type1", $temp);
+ if(count($links) <= 1 && $defaultlink == $defaultlink_orig) {
/* The API for this hook has changed as of 1.5.2 so that all plugin
arguments are passed in an array instead of each their own plugin
argument, and arguments are passed by reference, so instead of
returning any changes, changes should simply be made to the original
arguments themselves. */
- do_hook("attachment $type0/*", $temp=array(&$links,
- &$startMessage, &$id, &$urlMailbox, &$ent, &$defaultlink,
- &$display_filename, &$where, &$what));
+ $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent,
+ &$defaultlink, &$display_filename, &$where, &$what);
+ do_hook("attachment $type0/*", $temp);
}
/* The API for this hook has changed as of 1.5.2 so that all plugin
arguments are passed in an array instead of each their own plugin
argument, and arguments are passed by reference, so instead of
returning any changes, changes should simply be made to the original
arguments themselves. */
- do_hook("attachment */*", $temp=array(&$links,
- &$startMessage, &$id, &$urlMailbox, &$ent, &$defaultlink,
- &$display_filename, &$where, &$what));
+ $temp = array(&$links, &$startMessage, &$id, &$urlMailbox, &$ent,
+ &$defaultlink, &$display_filename, &$where, &$what);
+ // Do not let a generic plugin change the default link if a more
+ // specialized one already did it...
+ if ($defaultlink != $defaultlink_orig) {
+ $dummy = '';
+ $temp[5] = &$dummy;
+ }
+ do_hook("attachment */*", $temp);
$this_attachment = array();
$this_attachment['Name'] = decodeHeader($display_filename);
*
* @param string $string header string that has to be made readable
* @param boolean $utfencode change message in order to be readable on user's charset. defaults to true
- * @param boolean $htmlsave preserve spaces and sanitize html special characters. defaults to true
+ * @param boolean $htmlsafe preserve spaces and sanitize html special characters. defaults to true
* @param boolean $decide decide if string can be utfencoded. defaults to false
* @return string decoded header string
*/
-function decodeHeader ($string, $utfencode=true,$htmlsave=true,$decide=false) {
+function decodeHeader ($string, $utfencode=true,$htmlsafe=true,$decide=false) {
global $languages, $squirrelmail_language,$default_charset;
if (is_array($string)) {
$string = implode("\n", $string);
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) {
+ if ($htmlsafe) {
$ret .= ' ';
} else {
$ret .= ' ';
}
$iLastMatch = $i;
$j = $i;
- if ($htmlsave) {
+ if ($htmlsafe) {
$ret .= htmlspecialchars($res[1]);
} else {
$ret .= $res[1];
/* convert string to different charset,
* if functions asks for it (usually in compose)
*/
- $ret .= charset_convert($res[2],$replace,$default_charset,$htmlsave);
+ $ret .= charset_convert($res[2],$replace,$default_charset,$htmlsafe);
} else {
// convert string to html codes in order to display it
$ret .= charset_decode($res[2],$replace);
}
} else {
- if ($htmlsave) {
+ if ($htmlsafe) {
$replace = htmlspecialchars($replace);
}
$ret.= $replace;
/* convert string to different charset,
* if functions asks for it (usually in compose)
*/
- $replace = charset_convert($res[2], $replace,$default_charset,$htmlsave);
+ $replace = charset_convert($res[2], $replace,$default_charset,$htmlsafe);
} else {
// convert string to html codes in order to display it
$replace = charset_decode($res[2], $replace);
}
} else {
- if ($htmlsave) {
+ if ($htmlsafe) {
$replace = htmlspecialchars($replace);
}
}
$encoded = true;
}
if (!$encoded) {
- if ($htmlsave) {
+ if ($htmlsafe) {
$ret .= ' ';
} else {
$ret .= ' ';
}
}
- if (!$encoded && $htmlsave) {
+ if (!$encoded && $htmlsafe) {
$ret .= htmlspecialchars($chunk);
} else {
$ret .= $chunk;
}
/* remove the first added space */
if ($ret) {
- if ($htmlsave) {
+ if ($htmlsafe) {
$ret = substr($ret,5);
} else {
$ret = substr($ret,1);
$attvalue = trim(substr($attvalue,1,-1));
}
- if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) {
- $view_unsafe_images = false;
- }
+ // If there's no "view_unsafe_images" variable in the URL, turn unsafe
+ // images off by default.
+ sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE);
+
$secremoveimg = '../images/' . _("sec_remove_eng.png");
/**
$attvalue = $sQuote . $secremoveimg . $sQuote;
} else {
if (isset($aUrl['path'])) {
+
+ // No one has been able to show that image URIs
+ // can be exploited, so for now, no restrictions
+ // are made at all. If this proves to be a problem,
+ // the commented-out code below can be of help.
+ // (One consideration is that I see nothing in this
+ // function that specifically says that we will
+ // only ever arrive here when inspecting an image
+ // tag, although that does seem to be the end
+ // result - e.g., <script src="..."> where malicious
+ // image URIs are in fact a problem are already
+ // filtered out elsewhere.
+ /* ---------------------------------
// validate image extension.
$ext = strtolower(substr($aUrl['path'],strrpos($aUrl['path'],'.')));
if (!in_array($ext,array('.jpeg','.jpg','xjpeg','.gif','.bmp','.jpe','.png','.xbm'))) {
- $attvalue = $sQuote . SM_PATH . 'images/blank.png'. $sQuote;
+ // If URI is to something other than
+ // a regular image file, get the contents
+ // and try to see if it is an image.
+ // Don't use Fileinfo (finfo_file()) because
+ // we'd need to make the admin configure the
+ // location of the magic.mime file (FIXME: add finfo_file() support later?)
+ //
+ $mime_type = '';
+ if (function_exists('mime_content_type')
+ && ($FILE = @fopen($attvalue, 'rb', FALSE))) {
+
+ // fetch file
+ //
+ $file_contents = '';
+ while (!feof($FILE)) {
+ $file_contents .= fread($FILE, 8192);
+ }
+ fclose($FILE);
+
+ // store file locally
+ //
+ global $attachment_dir, $username;
+ $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
+ $localfilename = GenerateRandomString(32, '', 7);
+ $full_localfilename = "$hashed_attachment_dir/$localfilename";
+ while (file_exists($full_localfilename)) {
+ $localfilename = GenerateRandomString(32, '', 7);
+ $full_localfilename = "$hashed_attachment_dir/$localfilename";
+ }
+ $FILE = fopen("$hashed_attachment_dir/$localfilename", 'wb');
+ fwrite($FILE, $file_contents);
+ fclose($FILE);
+
+ // get mime type and remove file
+ //
+ $mime_type = mime_content_type("$hashed_attachment_dir/$localfilename");
+ unlink("$hashed_attachment_dir/$localfilename");
+ }
+ // debug: echo "$attvalue FILE TYPE IS $mime_type<HR>";
+ if (substr(strtolower($mime_type), 0, 5) != 'image') {
+ $attvalue = $sQuote . SM_PATH . 'images/blank.png'. $sQuote;
+ }
}
+ --------------------------------- */
} else {
$attvalue = $sQuote . SM_PATH . 'images/blank.png'. $sQuote;
}
$char = $body{$i};
switch ($char) {
case '<':
- $sToken .= $char;
+ $sToken = $char;
break;
case '/':
if ($sToken == '<') {
/**
- * First look for general BODY style declaration, which would be
- * like so:
- * body {background: blah-blah}
- * and change it to .bodyclass so we can just assign it to a <div>
- */
+ * First look for general BODY style declaration, which would be
+ * like so:
+ * body {background: blah-blah}
+ * 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");
/**
$content = str_replace($aValue,$aReplace,$content);
}
- /**
- * Remove any backslashes, entities, and extraneous whitespace.
- */
+ /**
+ * Remove any backslashes, entities, and extraneous whitespace.
+ */
$contentTemp = $content;
sq_defang($contentTemp);
sq_unspace($contentTemp);
$cidurl = preg_replace($match_str, $str_rep, $cidurl);
$linkurl = find_ent_id($cidurl, $message);
- /* in case of non-save cid links $httpurl should be replaced by a sort of
- unsave link image */
+ /* in case of non-safe cid links $httpurl should be replaced by a sort of
+ unsafe link image */
$httpurl = '';
/**
)
)
);
- if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) {
- $view_unsafe_images = false;
- }
+
+ // If there's no "view_unsafe_images" variable in the URL, turn unsafe
+ // images off by default.
+ sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET, FALSE);
+
if (!$view_unsafe_images){
/**
* Remove any references to http/https if view_unsafe_images set