Reinserting support for the "iframe_height" option. This might be done in a better...
[squirrelmail.git] / functions / mime.php
index 48dccdaee2649e5260232c1d49e1fba95575d7a7..c151ecf6f5cb2d6d30c52a7426fad33f3827ccc0 100644 (file)
@@ -60,17 +60,17 @@ function mime_structure ($bodystructure, $flags=array()) {
 
     if (!is_object($msg)) {
         global $color, $mailbox;
-        /* removed urldecode because $_GET is auto urldecoded ??? */
         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>';
-        plain_error_message( $errormessage, $color );
+        plain_error_message( $errormessage );
         echo '</body></html>';
         exit;
     }
     if (count($flags)) {
         foreach ($flags as $flag) {
+//FIXME: please document why it is we have to check the first char of the flag but we then go ahead and do a full string comparison anyway.  Is this a speed enhancement?  If not, let's keep it simple and just compare the full string and forget the switch block.
             $char = strtoupper($flag{1});
             switch ($char) {
                 case 'S':
@@ -147,6 +147,8 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1, $fetch_size=0) {
 //        }
     } 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) . '&amp;passed_id=' . $passed_id;
@@ -351,7 +353,8 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
     global $startMessage, $languages, $squirrelmail_language,
            $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;
+           $download_href, $unsafe_image_toggle_href, $unsafe_image_toggle_text,
+           $oTemplate, $nbsp;
 
     // workaround for not updated config.php
     if (! isset($use_iframe)) $use_iframe = false;
@@ -418,18 +421,22 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
 
                 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');
             } else {
                 // old way of html rendering
-                $body = magicHTML($body, $id, $message, $mailbox);
                 /**
                  * convert character set. charset_decode does not remove html special chars
                  * applied by magicHTML functions and does not sanitize them second time if
                  * fourth argument is true.
                  */
-                $body = charset_decode($body_message->header->getParameter('charset'),$body,false,true);
+                $charset = $body_message->header->getParameter('charset');
+                if (!empty($charset)) {
+                    $body = charset_decode($charset,$body,false,true);
+                }
+                $body = magicHTML($body, $id, $message, $mailbox);
             }
         } else {
             translateText($body, $wrap_at,
@@ -450,7 +457,8 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
             $link .= '&amp;passed_ent_id='.$passed_ent_id;
         }
         $download_href = SM_PATH . 'src/download.php?absolute_dl=true&amp;' . $link;
-        $download_and_unsafe_link .= '&nbsp;|&nbsp;<a href="'. $download_href .'">' . _("Download this as a file") .  '</a>';
+        $download_and_unsafe_link .= "$nbsp|$nbsp" 
+            . create_hyperlink($download_href, _("Download this as a file"));
         if ($view_unsafe_images) {
             $text = _("Hide Unsafe Images");
         } else {
@@ -464,7 +472,8 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
         if($text != '') {
             $unsafe_image_toggle_href = SM_PATH . 'src/read_body.php?'.$link;
             $unsafe_image_toggle_text = $text;
-            $download_and_unsafe_link .= '&nbsp;|&nbsp;<a href="'. $unsafe_image_toggle_href .'">' . $text . '</a>';
+            $download_and_unsafe_link .= "$nbsp|$nbsp"
+                . create_hyperlink($unsafe_image_toggle_href, $text);
         }
     }
     return $body;
@@ -553,32 +562,41 @@ function buildAttachmentArray($message, $exclude_id, $mailbox, $id) {
          * 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);
@@ -700,7 +718,7 @@ function decodeBody($body, $encoding) {
 /**
  * Decodes headers
  *
- * This functions decode strings that is encoded according to
+ * This function decodes strings that are encoded according to
  * RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text).
  * Patched by Christian Schmidt <christian@ostenfeld.dk>  23/03/2002
  *
@@ -1191,8 +1209,8 @@ function sq_fixIE_idiocy(&$attvalue) {
                         array('&#x029F;', '&#0671;' ,/* L UNICODE IPA Extension */
                               '&#x0280;', '&#0640;' ,/* R UNICODE IPA Extension */
                               '&#x0274;', '&#0628;' ,/* N UNICODE IPA Extension */
-                              '&#xFF25;', '&#65317' ,/* Unicode FULLWIDTH LATIN CAPITAL LETTER E */
-                              '&#xFF45;', '&#65349' ,/* Unicode FULLWIDTH LATIN SMALL LETTER E */
+                              '&#xFF25;', '&#65317;' ,/* Unicode FULLWIDTH LATIN CAPITAL LETTER E */
+                              '&#xFF45;', '&#65349;' ,/* Unicode FULLWIDTH LATIN SMALL LETTER E */
                               '&#xFF38;', '&#65336;',/* Unicode FULLWIDTH LATIN CAPITAL LETTER X */
                               '&#xFF58;', '&#65368;',/* Unicode FULLWIDTH LATIN SMALL LETTER X */
                               '&#xFF30;', '&#65328;',/* Unicode FULLWIDTH LATIN CAPITAL LETTER P */
@@ -1212,26 +1230,34 @@ function sq_fixIE_idiocy(&$attvalue) {
                               '&#xFF35;', '&#65333;',/* Unicode FULLWIDTH LATIN CAPITAL LETTER U */
                               '&#xFF55;', '&#65365;',/* Unicode FULLWIDTH LATIN SMALL LETTER U */
                               '&#x207F;', '&#8319;' ,/* Unicode SUPERSCRIPT LATIN SMALL LETTER N */
-                              '&#x8264;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER E */   // in unicode this is some Chinese char range
-                              '&#x8285;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER E */
-                              '&#x8277;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER X */
-                              '&#x8298;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER X */
-                              '&#x826F;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER P */
-                              '&#x8290;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER P */
-                              '&#x8271;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER R */
-                              '&#x8292;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER R */
-                              '&#x8272;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER S */
-                              '&#x8293;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER S */
-                              '&#x8268;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER I */
-                              '&#x8289;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER I */
-                              '&#x826E;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER O */
-                              '&#x828F;', /* Shift JIS FULLWIDTH LATIN SMALL LETTER O */
-                              '&#x826D;', /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER N */
-                              '&#x828E;'), /* Shift JIS FULLWIDTH LATIN SMALL LETTER N */
+                              "\xEF\xBC\xA5", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER E */   // in unicode this is some Chinese char range
+                              "\xEF\xBD\x85", /* Shift JIS FULLWIDTH LATIN SMALL LETTER E */
+                              "\xEF\xBC\xB8", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER X */
+                              "\xEF\xBD\x98", /* Shift JIS FULLWIDTH LATIN SMALL LETTER X */
+                              "\xEF\xBC\xB0", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER P */
+                              "\xEF\xBD\x90", /* Shift JIS FULLWIDTH LATIN SMALL LETTER P */
+                              "\xEF\xBC\xB2", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER R */
+                              "\xEF\xBD\x92", /* Shift JIS FULLWIDTH LATIN SMALL LETTER R */
+                              "\xEF\xBC\xB3", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER S */
+                              "\xEF\xBD\x93", /* Shift JIS FULLWIDTH LATIN SMALL LETTER S */
+                              "\xEF\xBC\xA9", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER I */
+                              "\xEF\xBD\x89", /* Shift JIS FULLWIDTH LATIN SMALL LETTER I */
+                              "\xEF\xBC\xAF", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER O */
+                              "\xEF\xBD\x8F", /* Shift JIS FULLWIDTH LATIN SMALL LETTER O */
+                              "\xEF\xBC\xAE", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER N */
+                              "\xEF\xBD\x8E", /* Shift JIS FULLWIDTH LATIN SMALL LETTER N */
+                              "\xEF\xBC\xAC", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER L */
+                              "\xEF\xBD\x8C", /* Shift JIS FULLWIDTH LATIN SMALL LETTER L */
+                              "\xEF\xBC\xB5", /* Shift JIS FULLWIDTH LATIN CAPITAL LETTER U */
+                              "\xEF\xBD\x95", /* Shift JIS FULLWIDTH LATIN SMALL LETTER U */
+                              "\xE2\x81\xBF", /* Shift JIS FULLWIDTH SUPERSCRIPT N */
+                              "\xCA\x9F", /* L UNICODE IPA Extension */
+                              "\xCA\x80", /* R UNICODE IPA Extension */
+                              "\xC9\xB4"),  /* N UNICODE IPA Extension */
                        array('l', 'l', 'r','r','n','n',
-                             'E','E','e','e','X','X','x','x','P','P','p','p','S','S','s','s','I','I',
-                             'i','i','O','O','o','o','N','N','n','n','L','L','l','l','U','U','u','u','n',
-                             'E','e','X','x','P','p','S','s','I','i','O','o','N','n'));
+                             'E','E','e','e','X','X','x','x','P','P','p','p','R','R','r','r','S','S','s','s','I','I',
+                             'i','i','O','O','o','o','N','N','n','n','L','L','l','l','U','U','u','u','n','n',
+                             'E','e','X','x','P','p','R','r','S','s','I','i','O','o','N','n','L','l','U','u','n','l','r','n'));
     $attvalue = str_replace($aDangerousCharsReplacementTable[0],$aDangerousCharsReplacementTable[1],$attvalue);
 
     // Escapes are useful for special characters like "{}[]()'&. In other cases they are
@@ -1746,38 +1772,34 @@ function sq_fixatts($tagname,
                             preg_replace($valmatch, $valrepl, $attvalue);
                         if ($newvalue != $attvalue){
                             $attary{$attname} = $newvalue;
+                            $attvalue = $newvalue;
                         }
                     }
                 }
             }
         }
-
-        /**
-         * Replace empty src tags with the blank image.  src is only used
-         * for frames, images, and image inputs.  Doing a replace should
-         * not affect them working as should be, however it will stop
-         * IE from being kicked off when src for img tags are not set
-         */
-        if (($attname == 'src') && ($attvalue == '""')) {
-            $attary{$attname} = '"' . SM_PATH . 'images/blank.png"';
-        }
-
-        /**
-         * Turn cid: urls into http-friendly ones.
-         */
-        if (preg_match("/^[\'\"]\s*cid:/si", $attvalue)){
-            $attary{$attname} = sq_cid2http($message, $id, $attvalue, $mailbox);
+        if ($attname == 'style') {
+            if (preg_match('/[\0-\37\200-\377]+/',$attvalue)) {
+                // 8bit and control characters in style attribute values can be used for XSS, remove them
+                $attary{$attname} = '"disallowed character"';
+            }
+            preg_match_all("/url\s*\((.+)\)/si",$attvalue,$aMatch);
+            if (count($aMatch)) {
+                foreach($aMatch[1] as $sMatch) {
+                    // url value
+                    $urlvalue = $sMatch;
+                    sq_fix_url($attname, $urlvalue, $message, $id, $mailbox,"'");
+                    $attary{$attname} = str_replace($sMatch,$urlvalue,$attvalue);
+                }
+            }
         }
-
         /**
-         * "Hack" fix for Outlook using propriatary outbind:// protocol in img tags.
-         * One day MS might actually make it match something useful, for now, falling
-         * back to using cid2http, so we can grab the blank.png.
+         * Use white list based filtering on attributes which can contain url's
          */
-        if (preg_match("/^[\'\"]\s*outbind:\/\//si", $attvalue)) {
-            $attary{$attname} = sq_cid2http($message, $id, $attvalue, $mailbox);
+        else if ($attname == 'href' || $attname == 'src' || $attname == 'background') {
+            sq_fix_url($attname, $attvalue, $message, $id, $mailbox);
+            $attary{$attname} = $attvalue;
         }
-
     }
     /**
      * See if we need to append any attributes to this tag.
@@ -1790,6 +1812,99 @@ function sq_fixatts($tagname,
     return $attary;
 }
 
+/**
+ * This function filters url's
+ *
+ * @param  $attvalue        String with attribute value to filter
+ * @param  $message         message object
+ * @param  $id               message id
+ * @param  $mailbox         mailbox
+ * @param  $sQuote          quoting characters around url's
+ */
+function sq_fix_url($attname, &$attvalue, $message, $id, $mailbox,$sQuote = '"') {
+    $attvalue = trim($attvalue);
+    if ($attvalue && ($attvalue[0] =='"'|| $attvalue[0] == "'")) {
+        // remove the double quotes
+        $sQuote = $attvalue[0];
+        $attvalue = trim(substr($attvalue,1,-1));
+    }
+
+    if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) {
+        $view_unsafe_images = false;
+    }
+    $secremoveimg = '../images/' . _("sec_remove_eng.png");
+
+    /**
+     * Replace empty src tags with the blank image.  src is only used
+     * for frames, images, and image inputs.  Doing a replace should
+     * not affect them working as should be, however it will stop
+     * IE from being kicked off when src for img tags are not set
+     */
+    if ($attvalue == '') {
+        $attvalue = '"' . SM_PATH . 'images/blank.png"';
+    } else {
+        // first, disallow 8 bit characters and control characters
+        if (preg_match('/[\0-\37\200-\377]+/',$attvalue)) {
+            switch ($attname) {
+                case 'href':
+                    $attvalue = $sQuote . 'http://invalid-stuff-detected.example.com' . $sQuote;
+                    break;
+                default:
+                    $attvalue = $sQuote . SM_PATH . 'images/blank.png'. $sQuote;
+                    break;
+            }
+        } else {
+            $aUrl = parse_url($attvalue);
+            if (isset($aUrl['scheme'])) {
+                switch(strtolower($aUrl['scheme'])) {
+                    case 'mailto':
+                    case 'http':
+                    case 'https':
+                    case 'ftp':
+                        if ($attname != 'href') {
+                            if ($view_unsafe_images == false) {
+                                $attvalue = $sQuote . $secremoveimg . $sQuote;
+                            } else {
+                                if (isset($aUrl['path'])) {
+                                    // 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;
+                                    }
+                                } else {
+                                    $attvalue = $sQuote . SM_PATH . 'images/blank.png'. $sQuote;
+                                }
+                            }
+                        }
+                        break;
+                    case 'outbind':
+                        /**
+                         * "Hack" fix for Outlook using propriatary outbind:// protocol in img tags.
+                         * One day MS might actually make it match something useful, for now, falling
+                         * back to using cid2http, so we can grab the blank.png.
+                         */
+                        $attvalue = sq_cid2http($message, $id, $attvalue, $mailbox);
+                        break;
+                    case 'cid':
+                        /**
+                            * Turn cid: urls into http-friendly ones.
+                            */
+                        $attvalue = sq_cid2http($message, $id, $attvalue, $mailbox);
+                        break;
+                    default:
+                        $attvalue = $sQuote . SM_PATH . 'images/blank.png' . $sQuote;
+                        break;
+                }
+            } else {
+                if (!(isset($aUrl['path']) && $aUrl['path'] == $secremoveimg)) {
+                    // parse_url did not lead to satisfying result
+                    $attvalue = $sQuote . SM_PATH . 'images/blank.png' . $sQuote;
+                }
+            }
+        }
+    }
+}
+
 /**
  * This function edits the style definition to make them friendly and
  * usable in SquirrelMail.
@@ -1801,7 +1916,6 @@ function sq_fixatts($tagname,
  * @return           a string with edited content.
  */
 function sq_fixstyle($body, $pos, $message, $id, $mailbox){
-    global $view_unsafe_images;
     $me = 'sq_fixstyle';
     // workaround for </style> in between comments
     $iCurrentPos = $pos;
@@ -1881,6 +1995,12 @@ function sq_fixstyle($body, $pos, $message, $id, $mailbox){
     //   $content = preg_replace("|url\s*\(\s*([\'\"])\s*\S+script\s*:.*?([\'\"])\s*\)|si",
     //                           "url(\\1$secremoveimg\\2)", $content);
 
+    // first check for 8bit sequences and disallowed control characters
+    if (preg_match('/[\16-\37\200-\377]+/',$content)) {
+        $content = '<!-- style block removed by html filter due to presence of 8bit characters -->';
+        return array($content, $newpos);
+    }
+
     // IE Sucks hard. We have a special function for it.
     sq_fixIE_idiocy($content);
 
@@ -1890,48 +2010,19 @@ function sq_fixstyle($body, $pos, $message, $id, $mailbox){
     // translate ur\l and variations (IE parses that)
     // TODO check if the sq_fixIE_idiocy function already handles this.
     $content = preg_replace("/(\\\\)?u(\\\\)?r(\\\\)?l(\\\\)?/i", 'url', $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);
-
-                } else {
-                    $content = preg_replace('/url/i',"u\0r\0l",$content);
-                }
-                break;
-            /**
-             * Fix urls that refer to cid:
-             */
-            case 'cid':
-                $cidurl = 'cid:'. $matches[2];
-                $httpurl = sq_cid2http($message, $id, $cidurl, $mailbox);
-                // escape parentheses that can modify the regular expression
-                $cidurl = str_replace(array('(',')'),array('\\(','\\)'),$cidurl);
-                $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;
+    preg_match_all("/url\s*\((.+)\)/si",$content,$aMatch);
+    if (count($aMatch)) {
+        $aValue = $aReplace = array();
+        foreach($aMatch[1] as $sMatch) {
+            // url value
+            $urlvalue = $sMatch;
+            sq_fix_url('style',$urlvalue, $message, $id, $mailbox,"'");
+            $aValue[] = $sMatch;
+            $aReplace[] = $urlvalue;
         }
+        $content = str_replace($aValue,$aReplace,$content);
     }
-    // remove NUL
-    $content = str_replace("\0", "", $content);
+
    /**
     * Remove any backslashes, entities, and extraneous whitespace.
     */
@@ -2368,7 +2459,7 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX', $take_mailto_links
                     "idiocy",
                     "idiocy",
                     "idiocy",
-                    "",
+                    "idiocy",
                     "url",
                     "url(\\1#\\1)",
                     "url(\\1#\\1)",
@@ -2414,7 +2505,7 @@ function magicHTML($body, $id, $message, $mailbox = 'INBOX', $take_mailto_links
                            $id,
                            $mailbox
                            );
-    if (preg_match("|$secremoveimg|i", $trusted)){
+    if (strpos($trusted,$secremoveimg)){
         $has_unsafe_images = true;
     }