X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fmime.php;h=7bbfa3741d32a3b4460d3e287e40fe11077597cd;hb=41336c5f3546db383788319f4a5e325202f904ee;hp=4193f50856dc361c83f67fd993bbe22ec8cbdf28;hpb=1fbbe1d491ac3dd29c728a02625f4396a0c5993f;p=squirrelmail.git
diff --git a/functions/mime.php b/functions/mime.php
index 4193f508..7bbfa374 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,27 +92,84 @@ function mime_structure ($imap_stream, $header) {
* to mime_get_elements()
*/
function mime_parse_structure ($structure, $ent_id) {
-
+ global $mailbox;
+ $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);
- $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);
+ /* check if we are dealing with a new entity-level */
+ $i = strrpos($ent_id,'.');
+ if ($i>0) {
+ $ent = substr($ent_id, $i+1);
+ } else {
+ $ent = '';
+ }
+ /* add "forgotten" parent entities (alternative and relative) */
+ if ($ent == '0') {
+ /* new entity levels have information about the type (type1) and
+ * the properties. This information is situated at the end of the
+ * structure string like for example (example between the brackets)
+ * [ "RELATED" ("BOUNDARY" "myboundary" "TYPE" "plain/html") ]
+ */
+
+ /* get the involved properties for parsing to mime_get_properties */
+ $startprop = strrpos($structure,'(');
+ $properties_str = substr($structure,$startprop);
+ $endprop = mime_match_parenthesis ($startprop, $structure);
+ $propstr = substr($structure, $startprop + 1, ($endprop - $startprop)-1);
+ /* cut off the used properties */
+ if ($startprop) {
+ $structure_end = substr($structure, $endprop+2);
+ $structure = trim(substr($structure,0,$startprop));
+ }
+
+ /* get type1 */
+ $pos = strrpos($structure,' ');
+ $type1 = strtolower(substr($structure, $pos+2, (count($structure)-2)));
+
+ /* cut off type1 */
+ if ($pos && $startprop) {
+ $structure = trim(substr($structure, 0, $pos));
+ }
+
+ /* process the found information */
+ $properties = mime_get_props($properties, $properties_str);
+ 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'];
+ }
+ }
+ $structure = $structure . ' ' . $structure_end;
+ }
+ $element = substr($structure, $start+1, ($end - $start)-1);
+ $ent_id = mime_increment_id ($ent_id);
+ $newmsg = mime_parse_structure ($element, $ent_id);
+ /* set mailbox in case of message/rfc822 entities */
+ if (isset($newmsg->header->type0) && isset($newmsg->header->type1)) {
+ if ($newmsg->header->type0 == 'message' && $newmsg->header->type1 == 'rfc822') {
+ $newmsg->header->mailbox=$mailbox;
+ }
+ }
+ $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;
}
+
/* Increments the element ID. An element id can look like any of
* the following: 1, 1.2, 4.3.2.4.1, etc. This function increments
* the last number of the element id, changing 1.2 to 1.3.
@@ -155,7 +213,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 +308,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 +336,6 @@ function mime_get_props ($props, $structure) {
while (strlen($structure) > 0) {
$structure = trim($structure);
$char = $structure{0};
-
if ($char == '"') {
$pos = 1;
$tmp = '';
@@ -301,20 +355,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);
@@ -527,14 +585,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 +603,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,7 +655,7 @@ function findDisplayEntityHTML ($message) {
return $entity;
}
}
-
+
return 0;
}
@@ -655,6 +714,37 @@ function translateText(&$body, $wrap_at, $charset) {
$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
@@ -672,19 +762,16 @@ function formatBody($imap_stream, $message, $color, $wrap_at) {
$id = $message->header->id;
$urlmailbox = urlencode($message->header->mailbox);
-
// 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') {
@@ -708,7 +795,7 @@ function formatBody($imap_stream, $message, $color, $wrap_at) {
}
/** Display the ATTACHMENTS: message if there's more than one part **/
- if (isset($message->entities[0])) {
+ if (isset($message->entities[1])) {
$body .= formatAttachments ($message, $ent_num, $message->header->mailbox, $id);
}
} else {
@@ -742,8 +829,10 @@ function formatAttachments($message, $ent_id, $mailbox, $id) {
$header = $message->header;
$type0 = strtolower($header->type0);
$type1 = strtolower($header->type1);
- $name = decodeHeader($header->name);
-
+ $name = '';
+ if (isset($header->name)) {
+ $name = decodeHeader($header->name);
+ }
if ($type0 =='message' && $type1 == 'rfc822') {
$filename = decodeHeader($message->header->filename);
@@ -842,7 +931,7 @@ function formatAttachments($message, $ent_id, $mailbox, $id) {
$DefaultLink =
"../src/download.php?startMessage=$startMessage&passed_id=$id&mailbox=$urlMailbox&passed_ent_id=$ent";
if ($where && $what) {
- $DefaultLink .= '&where=' . urlencode($where) . '&what=' . urlencode($what);
+ $DefaultLink = '&where='. urlencode($where).'&what='.urlencode($what);
}
$Links['download link']['text'] = _("download");
$Links['download link']['href'] =
@@ -1001,421 +1090,960 @@ function encodeHeader ($string) {
return( $string );
}
-/*
- Strips dangerous tags from html messages.
-*/
-function MagicHTML( $body, $id ) {
-
- global $message, $HTTP_SERVER_VARS,
- $attachment_common_show_images;
-
- $attachment_common_show_images =
- FALSE; // Don't display attached images in HTML mode
- $j = strlen( $body ); // Legnth of the HTML
- $ret = ''; // Returned string
- $bgcolor = '#ffffff'; // Background style color (defaults to white)
- $textcolor = '#000000'; // Foreground style color (defaults to black)
- $leftmargin = ''; // Left margin style
- $title = ''; // HTML title if any
+/* This function trys to locate the entity_id of a specific mime element */
- $i = 0;
- while ( $i < $j ) {
- if ( $body{$i} == '<' ) {
- $pos = $i + 1;
- $tag = '';
- while ($body{$pos} == ' ' || $body{$pos} == "\t" ||
- $body{$pos} == "\n" ) {
- $pos ++;
- }
- while (strlen($tag) < 4 && $body{$pos} != ' ' &&
- $body{$pos} != "\t" && $body{$pos} != "\n" &&
- $pos < $j ) {
- $tag .= $body{$pos};
- $pos ++;
- }
- /*
- A comment in HTML is only three characters and isn't
- guaranteed to have a space after it. This fudges so
- it will be caught by the switch statement.
- */
- if (ereg("!--", $tag)) {
- $tag = "!-- ";
- }
- switch( strtoupper( $tag ) ) {
- // Strips the entire tag and contents
- case 'APPL':
- case 'EMBE':
- case 'FRAM':
- case 'SCRI':
- case 'OBJE':
- $etg = '/' . $tag;
- while ( $body{$i+1}.$body{$i+2}.$body{$i+3}.$body{$i+4}.$body{$i+5} <> $etg &&
- $i < $j ) $i++;
- while ( $i < $j && $body{++$i} <> '>' );
- // $ret .= "";
- break;
- // Substitute Title
- case 'TITL':
- $i += 5;
- while ( $body{$i} <> '>' && //
- $i < $j )
- $i++;
- $i++;
- $title = '';
- while ( $body{$i} <> '<' && //
- $i < $j ) {
- $title .= $body{$i};
- $i++;
- }
- $i += 7;
- break;
- // Destroy these tags
- case 'HTML':
- case 'HEAD':
- case '/HTM':
- case '/HEA':
- case '!DOC':
- case 'META':
- //case 'DIV ':
- //case '/DIV':
- case '!-- ':
- $i += 4;
- while ( $body{$i} <> '>' &&
- $i < $j )
- $i++;
- // $i++;
- break;
- case 'STYL':
- $i += 5;
- while ( $body{$i} <> '>' && //
- $i < $j )
- $i++;
- $i++;
- // We parse the style to look for interesting stuff
- $styleblk = '';
- while ( $body{$i} <> '>' &&
- $i < $j ) {
- // First we get the name of the style
- $style = '';
- while ( $body{$i} <> '>' &&
- $body{$i} <> '<' &&
- $body{$i} <> '{' &&
- $i < $j ) {
- if ( isnoSep( $body{$i} ) )
- $style .= $body{$i};
- $i++;
- }
- stripComments( $i, $j, $body );
- $style = strtoupper( trim( $style ) );
- if ( $style == 'BODY' ) {
- // Next we look into the definitions of the body style
- while ( $body{$i} <> '>' &&
- $body{$i} <> '}' &&
- $i < $j ) {
- // We look for the background color if any.
- if ( substr( $body, $i, 17 ) == 'BACKGROUND-COLOR:' ) {
- $i += 17;
- $bgcolor = getStyleData( $i, $j, $body );
- } elseif ( substr( $body, $i, 12 ) == 'MARGIN-LEFT:' ) {
- $i += 12;
- $leftmargin = getStyleData( $i, $j, $body );
- }
- $i++;
- }
- } else {
- // Other style are mantained
- $styleblk .= "$style ";
- while ( $body{$i} <> '>' &&
- $body{$i} <> '<' &&
- $body{$i} <> '}' &&
- $i < $j ) {
- $styleblk .= $body{$i};
- $i++;
- }
- $styleblk .= $body{$i};
- }
- stripComments( $i, $j, $body );
- if ( $body{$i} <> '>' )
- $i++;
- }
- if ( $styleblk <> '' )
- $ret .= "
+ * @return a string with edited content.
+ */
+function sq_fixstyle($message, $id, $content){
+ global $view_unsafe_images;
+ $me = "sq_fixstyle";
+ /**
+ * 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
+ */
+ $content = preg_replace("|body(\s*\{.*?\})|si", ".bodyclass\\1", $content);
+ $secremoveimg = "../images/" . _("sec_remove_eng.png");
+ /**
+ * Fix url('blah') declarations.
+ */
+ $content = preg_replace("|url\(([\'\"])\s*\S+script\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*https*:.*?([\'\"])\)|si",
+ "url(\\1$secremoveimg\\2)", $content);
+ }
+
+ /**
+ * Fix urls that refer to cid:
+ */
+ while (preg_match("|url\(([\'\"]\s*cid:.*?[\'\"])\)|si", $content,
+ $matches)){
+ $cidurl = $matches{1};
+ $httpurl = sq_cid2http($message, $id, $cidurl);
+ $content = preg_replace("|url\($cidurl\)|si",
+ "url($httpurl)", $content);
+ }
-/* This function trys to locate the entity_id of a specific mime element */
+ /**
+ * Fix stupid expression: declarations which lead to vulnerabilities
+ * in IE.
+ */
+ $content = preg_replace("/expression\s*:/si", "idiocy:", $content);
+ return $content;
+}
-function find_ent_id( $id, $message ) {
+/**
+ * This function converts cid: url's into the ones that can be viewed in
+ * the browser.
+ *
+ * @param $message the message object
+ * @param $id the message id
+ * @param $cidurl the cid: url.
+ * @return a string with a http-friendly url
+ */
+function sq_cid2http($message, $id, $cidurl){
+ /**
+ * Get rid of quotes.
+ */
+ $quotchar = substr($cidurl, 0, 1);
+ $cidurl = str_replace($quotchar, "", $cidurl);
+ $cidurl = substr(trim($cidurl), 4);
+ $httpurl = $quotchar . "../src/download.php?absolute_dl=true&" .
+ "passed_id=$id&mailbox=" . urlencode($message->header->mailbox) .
+ "&passed_ent_id=" . find_ent_id($cidurl, $message) . $quotchar;
+ return $httpurl;
+}
- $ret = '';
- for ($i=0; $ret == '' && $i < count($message->entities); $i++) {
+/**
+ * This function changes the tag into a
tag since we
+ * can't really have a body-within-body.
+ *
+ * @param $attary an array of attributes and values of
+ * @return a modified array of attributes to be set for
+ */
+function sq_body2div($attary){
+ $me = "sq_body2div";
+ $divattary = Array("class"=>"'bodyclass'");
+ $bgcolor="#ffffff";
+ $text="#000000";
+ $styledef="";
+ if (is_array($attary) && sizeof($attary) > 0){
+ foreach ($attary as $attname=>$attvalue){
+ $quotchar = substr($attvalue, 0, 1);
+ $attvalue = str_replace($quotchar, "", $attvalue);
+ switch ($attname){
+ case "background":
+ $styledef .= "background-image: url('$attvalue'); ";
+ break;
+ case "bgcolor":
+ $styledef .= "background-color: $attvalue; ";
+ break;
+ case "text":
+ $styledef .= "color: $attvalue; ";
+ }
+ }
+ if (strlen($styledef) > 0){
+ $divattary{"style"} = "\"$styledef\"";
+ }
+ }
+ return $divattary;
+}
- if ( $message->entities[$i]->header->entity_id == '' ) {
- $ret = find_ent_id( $id, $message->entities[$i] );
+/**
+ * This is the main function and the one you should actually be calling.
+ * There are several variables you should be aware of an which need
+ * special description.
+ *
+ * Since the description is quite lengthy, see it here:
+ * http://www.mricon.com/html/phpfilter.html
+ *
+ * @param $body the string with HTML you wish to filter
+ * @param $tag_list see description above
+ * @param $rm_tags_with_content see description above
+ * @param $self_closing_tags see description above
+ * @param $force_tag_closing see description above
+ * @param $rm_attnames see description above
+ * @param $bad_attvals see description above
+ * @param $add_attr_to_tag see description above
+ * @param $message message object
+ * @param $id message id
+ * @return sanitized html safe to show on your pages.
+ */
+function sq_sanitize($body,
+ $tag_list,
+ $rm_tags_with_content,
+ $self_closing_tags,
+ $force_tag_closing,
+ $rm_attnames,
+ $bad_attvals,
+ $add_attr_to_tag,
+ $message,
+ $id
+ ){
+ $me = "sq_sanitize";
+ /**
+ * Normalize rm_tags and rm_tags_with_content.
+ */
+ @array_walk($rm_tags, 'sq_casenormalize');
+ @array_walk($rm_tags_with_content, 'sq_casenormalize');
+ @array_walk($self_closing_tags, 'sq_casenormalize');
+ /**
+ * See if tag_list is of tags to remove or tags to allow.
+ * false means remove these tags
+ * true means allow these tags
+ */
+ $rm_tags = array_shift($tag_list);
+ $curpos = 0;
+ $open_tags = Array();
+ $trusted = "\n";
+ $skip_content = false;
+
+ while (($curtag=sq_getnxtag($body, $curpos)) != FALSE){
+ list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;
+ $free_content = substr($body, $curpos, $lt-$curpos);
+ /**
+ * Take care of . Edit the
+ * content before we apply it.
+ */
+ $free_content = sq_fixstyle($message, $id, $free_content);
+ }
+ if ($skip_content == false){
+ $trusted .= $free_content;
} else {
- if ( strcasecmp( $message->entities[$i]->header->id, $id ) == 0 )
- $ret = $message->entities[$i]->header->entity_id;
}
-
+ if ($tagname != FALSE){
+ if ($tagtype == 2){
+ if ($skip_content == $tagname){
+ /**
+ * Got to the end of tag we needed to remove.
+ */
+ $tagname = false;
+ $skip_content = false;
+ } else {
+ if ($skip_content == false){
+ if ($tagname == "body"){
+ $tagname = "div";
+ } else {
+ if (isset($open_tags{$tagname}) &&
+ $open_tags{$tagname} > 0){
+ $open_tags{$tagname}--;
+ } else {
+ $tagname = false;
+ }
+ }
+ } else {
+ }
+ }
+ } else {
+ /**
+ * $rm_tags_with_content
+ */
+ if ($skip_content == false){
+ /**
+ * See if this is a self-closing type and change
+ * tagtype appropriately.
+ */
+ if ($tagtype == 1
+ && in_array($tagname, $self_closing_tags)){
+ $tagtype=3;
+ }
+ /**
+ * See if we should skip this tag and any content
+ * inside it.
+ */
+ if ($tagtype == 1 &&
+ in_array($tagname, $rm_tags_with_content)){
+ $skip_content = $tagname;
+ } else {
+ if (($rm_tags == false
+ && in_array($tagname, $tag_list)) ||
+ ($rm_tags == true &&
+ !in_array($tagname, $tag_list))){
+ $tagname = false;
+ } else {
+ if ($tagtype == 1){
+ if (isset($open_tags{$tagname})){
+ $open_tags{$tagname}++;
+ } else {
+ $open_tags{$tagname}=1;
+ }
+ }
+ /**
+ * This is where we run other checks.
+ */
+ if (is_array($attary) && sizeof($attary) > 0){
+ $attary = sq_fixatts($tagname,
+ $attary,
+ $rm_attnames,
+ $bad_attvals,
+ $add_attr_to_tag,
+ $message,
+ $id
+ );
+ }
+ /**
+ * Convert body into div.
+ */
+ if ($tagname == "body"){
+ $tagname = "div";
+ $attary = sq_body2div($attary, $message, $id);
+ }
+ }
+ }
+ } else {
+ }
+ }
+ if ($tagname != false && $skip_content == false){
+ $trusted .= sq_tagprint($tagname, $attary, $tagtype);
+ }
+ } else {
+ }
+ $curpos = $gt+1;
+ }
+ $trusted .= substr($body, $curpos, strlen($body)-$curpos);
+ if ($force_tag_closing == true){
+ foreach ($open_tags as $tagname=>$opentimes){
+ while ($opentimes > 0){
+ $trusted .= '' . $tagname . '>';
+ $opentimes--;
+ }
+ }
+ $trusted .= "\n";
}
+ $trusted .= "\n";
+ return $trusted;
+}
- return( $ret );
+/**
+ * This is a wrapper function to call html sanitizing routines.
+ *
+ * @param $body the body of the message
+ * @param $id the id of the message
+ * @return a string with html safe to display in the browser.
+ */
+function magicHTML($body, $id){
+ global $attachment_common_show_images, $view_unsafe_images,
+ $has_unsafe_images, $message;
+ /**
+ * Don't display attached images in HTML mode.
+ */
+ $attachment_common_show_images = false;
+ $tag_list = Array(
+ false,
+ "object",
+ "meta",
+ "html",
+ "head",
+ "base"
+ );
+
+ $rm_tags_with_content = Array(
+ "script",
+ "applet",
+ "embed",
+ "title"
+ );
+
+ $self_closing_tags = Array(
+ "img",
+ "br",
+ "hr",
+ "input"
+ );
+
+ $force_tag_closing = false;
+
+ $rm_attnames = Array(
+ "/.*/" =>
+ Array(
+ "/target/si",
+ "/^on.*/si"
+ )
+ );
+
+ $secremoveimg = "../images/" . _("sec_remove_eng.png");
+ $bad_attvals = Array(
+ "/.*/" =>
+ Array(
+ "/^src|background|href|action/i" =>
+ Array(
+ Array(
+ "|^([\'\"])\s*\.\./.*([\'\"])|si",
+ "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si"
+ ),
+ Array(
+ "\\1$secremoveimg\\2",
+ "\\1$secremoveimg\\2"
+ )
+ ),
+ "/^style/si" =>
+ Array(
+ Array(
+ "/expression\s*:/si",
+ "|url\(([\'\"])\s*\.\./.*([\'\"])\)|si",
+ "/url\(([\'\"])\s*\S+script:.*([\'\"])\)/si"
+ ),
+ Array(
+ "idiocy:",
+ "url(\\1$secremoveimg\\2)",
+ "url(\\1$secremoveimg\\2)"
+ )
+ )
+ )
+ );
+ if (!$view_unsafe_images){
+ /**
+ * Remove any references to http/https if view_unsafe_images set
+ * to false.
+ */
+ $addendum = Array(
+ "/.*/" =>
+ Array(
+ "/^src|background/i" =>
+ Array(
+ Array(
+ "/^([\'\"])\s*https*:.*([\'\"])/si"
+ ),
+ Array(
+ "\\1$secremoveimg\\2"
+ )
+ ),
+ "/^style/si" =>
+ Array(
+ Array(
+ "/url\(([\'\"])\s*https*:.*([\'\"])\)/si"
+ ),
+ Array(
+ "url(\\1$secremoveimg\\2)"
+ )
+ )
+ )
+ );
+ $bad_attvals = array_merge($bad_attvals, $addendum);
+ }
+ $add_attr_to_tag = Array(
+ "/^a$/si" => Array('target'=>'"_new"')
+ );
+ $trusted = sq_sanitize($body,
+ $tag_list,
+ $rm_tags_with_content,
+ $self_closing_tags,
+ $force_tag_closing,
+ $rm_attnames,
+ $bad_attvals,
+ $add_attr_to_tag,
+ $message,
+ $id
+ );
+ if (preg_match("|$secremoveimg|si", $trusted)){
+ $has_unsafe_images = true;
+ }
+ return $trusted;
}
-?>
+?>
\ No newline at end of file