First, more formatting conventions.
[squirrelmail.git] / functions / mime.php
index eb9dbd6cf118b86367c4cc1e46bf652cdfbc92ce..28c7e5545f03ffe7e48a6c58d2a398ee6e214069 100644 (file)
@@ -28,46 +28,59 @@ function mime_structure ($bodystructure, $flags=array()) {
 
     // isolate the body structure and remove beginning and end parenthesis
     $read = trim(substr ($bodystructure, strpos(strtolower($bodystructure), 'bodystructure') + 13));
-    $msg = &new message();
+    $msg =& new Message();
     $read = trim(substr ($read, 0, -1));
     $res = $msg->parseStructure($read);
     $msg = $res[0];
+    if (!is_object($msg)) {
+        include_once( '../functions/display_messages.php' );
+       global $color, $mailbox;
+        displayPageHeader( $color, urldecode($mailbox) );
+        echo "<BODY TEXT=\"$color[8]\" BGCOLOR=\"$color[4]\" LINK=\"$color[7]\" VLINK=\"$color[7]\" ALINK=\"$color[7]\">\n\n" .
+         '<CENTER>';
+       $errormessage = _("Squirrelmail could not decode the bodystructure of the message");
+       $errormessage .= '<BR>'._("the provided bodystructure by your imap-server").':<BR><BR>';
+        $errormessage .= '<table><tr><td>'.htmlspecialchars($read).'</td></tr></table>';
+        plain_error_message( $errormessage, $color );
+       echo '</body></html>';
+        exit;
+    }
     $msg->setEnt('0');
     if (count($flags)) {
-       foreach ($flags as $flag) {
-          $char = strtoupper($flag{1});
-         switch ($char) {
-            case 'S':
-              if (strtolower($flag) == '\\seen') {
-                 $msg->is_seen = true;
-              }
-              break;
-            case 'A':
-              if (strtolower($flag) == '\\answered') {
-                 $msg->is_answered = true;
-              }
-              break;
-            case 'D':
-              if (strtolower($flag) == '\\deleted') {
-                 $msg->is_deleted = true;
-              }
-              break;
-            case 'F':
-              if (strtolower($flag) == '\\flagged') {
-                 $msg->is_flagged = true;
-              }
-              break;
-            case 'M':
-              if (strtolower($flag) == '$mdnsent') {
-                 $msg->is_mdnsent = true;
-              }
-              break;
-            default:
-              break;
-          }
-       }
+        foreach ($flags as $flag) {
+            $char = strtoupper($flag{1});
+            switch ($char) {
+            case 'S':
+                if (strtolower($flag) == '\\seen') {
+                    $msg->is_seen = true;
+                }
+                break;
+            case 'A':
+                if (strtolower($flag) == '\\answered') {
+                    $msg->is_answered = true;
+                }
+                break;
+            case 'D':
+                if (strtolower($flag) == '\\deleted') {
+                    $msg->is_deleted = true;
+                }
+                break;
+            case 'F':
+                if (strtolower($flag) == '\\flagged') {
+                    $msg->is_flagged = true;
+                }
+                break;
+            case 'M':
+                if (strtolower($flag) == '$mdnsent') {
+                    $msg->is_mdnsent = true;
+                }
+                break;
+            default:
+                break;
+            }
+        }
     }
-//    listEntities($msg);
+    //    listEntities($msg);
     return( $msg );
 }
 
@@ -198,24 +211,6 @@ function mime_print_body_lines ($imap_stream, $id, $ent_id, $encoding) {
 
 /* -[ END MIME DECODING ]----------------------------------------------------------- */
 
-/* findDisplayEntity
- * Checks to see if $message contains content of type $type0/$type1
- * returns the first entity number it finds of that type, or NULL if
- * none is found.  Takes optional argument $start to allow the caller
- * to continue where they left off
- */
-function findDisplayEntity($message, $type0, $type1, $start=0) {
-    if ($message) {
-        for ($i = $start;isset($message->entities[$i]); $i++) {
-            $entity = $message->entities[$i];
-            if ($entity->type0 == $type0 && $entity->type1 == $type1) {
-                return $i;
-            }
-        }
-    }
-    return NULL;
-}
-
 // This is here for debugging purposese.  It will print out a list
 // of all the entity IDs that are in the $message object.
 
@@ -340,24 +335,30 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
     $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 = 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') {
             if ( $show_html_default <> 1 ) {
+                $entity_conv = array('&nbsp;' => ' ',
+                                     '&gt;'   => '>',
+                                     '&lt;'   => '<');
                 $body = strip_tags( $body );
-                translateText($body, $wrap_at, 
-                 $body_message->header->getParameter['charset']);
+                $body = strtr($body, $entity_conv);
+                $body = trim($body);
+                translateText($body, $wrap_at,
+                              $body_message->header->getParameter('charset'));
             } else {
                 $body = magicHTML( $body, $id, $message, $mailbox );
             }
         } else {
             translateText($body, $wrap_at, 
-              $body_message->header->getParameter('charset'));
+                             $body_message->header->getParameter('charset'));
         }
 
         if ($has_unsafe_images) {
@@ -373,8 +374,7 @@ function formatBody($imap_stream, $message, $color, $wrap_at, $ent_num, $id, $ma
 
 
 function formatAttachments($message, $exclude_id, $mailbox, $id) {
-    global $where, $what;
-    global $startMessage, $color;
+    global $where, $what, $startMessage, $color;
     static $ShownHTML = 0;
 
     $att_ar = $message->getAttachments($exclude_id);
@@ -393,7 +393,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) {
         $name = '';
         $Links['download link']['text'] = _("download");
         $Links['download link']['href'] =
-                "../src/download.php?absolute_dl=true&amp;passed_id=$id&amp;mailbox=$urlMailbox&amp;passed_ent_id=$ent";
+                "../src/download.php?absolute_dl=true&amp;passed_id=$id&amp;mailbox=$urlMailbox&amp;ent_id=$ent";
         $ImageURL = '';
         if ($type0 =='message' && $type1 == 'rfc822') {
             $default_page = '../src/read_body.php';
@@ -410,18 +410,26 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) {
            $description = $from_name;
         } else {
             $default_page = '../src/download.php';
-            $filename = decodeHeader($header->disposition->getProperty('filename'));
-            if (trim($filename) == '') {
-                $name = decodeHeader($header->disposition->getProperty('name'));
-                if (trim($name) == '') {
-                    if ( trim( $header->id ) == '' )
+           if (is_object($header->disposition)) {
+               $filename = decodeHeader($header->disposition->getProperty('filename'));
+               if (trim($filename) == '') {
+                  $name = decodeHeader($header->disposition->getProperty('name'));
+                  if (trim($name) == '') {
+                     if ( trim( $header->id ) == '' )
                         $filename = 'untitled-[' . $ent . ']' ;
-                    else
+                     else
                         $filename = 'cid: ' . $header->id;
-                } else {
-                    $filename = $name;
-                }
-            }
+                  } else {
+                     $filename = $name;
+                  }
+               }
+           } else {
+              if ( trim( $header->id ) == '' )
+                  $filename = 'untitled-[' . $ent . ']' ;
+               else
+                  $filename = 'cid: ' . $header->id;
+           }
+
             if ($header->description) {
                 $description = htmlspecialchars($header->description);
             } else {
@@ -430,9 +438,14 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) {
         }
 
         $display_filename = $filename;
+       if (isset($passed_ent_id)) {
+          $passed_ent_id_link = '&amp;passed_ent_id='.$passed_ent_id;
+       } else {
+          $passed_ent_id_link = '';
+       }
         $DefaultLink = $default_page . "?startMessage=$startMessage"
                      . "&amp;passed_id=$id&amp;mailbox=$urlMailbox"
-                     . "&amp;passed_ent_id=$ent";
+                     . '&amp;ent_id='.$ent.$passed_ent_id_link;
         if ($where && $what) {
            $DefaultLink = '&amp;where='. urlencode($where).'&amp;what='.urlencode($what);
         }
@@ -477,24 +490,32 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) {
 
 /** this function decodes the body depending on the encoding type. **/
 function decodeBody($body, $encoding) {
-  $body = str_replace("\r\n", "\n", $body);
-  $encoding = strtolower($encoding);
-
-  global $show_html_default;
-
-  if ($encoding == 'quoted-printable' ||
-      $encoding == 'quoted_printable') {
-     $body = quoted_printable_decode($body);
-
-     while (ereg("=\n", $body))
-        $body = ereg_replace ("=\n", "", $body);
+    global $languages, $squirrelmail_language;
 
-  } else if ($encoding == 'base64') {
-     $body = base64_decode($body);
-  }
-
-  // All other encodings are returned raw.
-  return $body;
+    $body = str_replace("\r\n", "\n", $body);
+    $encoding = strtolower($encoding);
+    
+    global $show_html_default;
+    
+    if ($encoding == 'quoted-printable' ||
+    $encoding == 'quoted_printable') {
+        $body = quoted_printable_decode($body);
+    
+        while (ereg("=\n", $body)) {
+            $body = ereg_replace ("=\n", '', $body);
+        }
+    
+    } else if ($encoding == 'base64') {
+        $body = base64_decode($body);
+    }
+    
+    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
+        function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
+        $body = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $body);
+    }
+    
+    // All other encodings are returned raw.
+    return( $body );
 }
 
 /*
@@ -503,9 +524,16 @@ function decodeBody($body, $encoding) {
  * Patched by Christian Schmidt <christian@ostenfeld.dk>  23/03/2002
  */
 function decodeHeader ($string, $utfencode=true) {
+    global $languages, $squirrelmail_language;
     if (is_array($string)) {
         $string = implode("\n", $string);
     }
+
+    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
+        function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
+        $string = $languages[$squirrelmail_language]['XTRA_CODE']('decodeheader', $string);
+    }
+
     $i = 0;
     while (preg_match('/^(.{' . $i . '})(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=/Ui', 
                       $string, $res)) {
@@ -539,7 +567,12 @@ function decodeHeader ($string, $utfencode=true) {
  * be encoded.
  */
 function encodeHeader ($string) {
-    global $default_charset;
+    global $default_charset, $languages, $squirrelmail_language;
+
+    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
+        function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
+        return  $languages[$squirrelmail_language]['XTRA_CODE']('encodeheader', $string);
+    }
 
     // Encode only if the string contains 8-bit characters or =?
     $j = strlen( $string  );
@@ -584,13 +617,26 @@ function find_ent_id( $id, $message ) {
        if ( $message->entities[$i]->header->type0 == 'multipart')  {    
            $ret = find_ent_id( $id, $message->entities[$i] );
         } else {
-            if ( strcasecmp( $message->entities[$i]->header->id, $id ) == 0 )
-                $ret = $message->entities[$i]->entity_id;
+            if ( strcasecmp( $message->entities[$i]->header->id, $id ) == 0 ) {
+               if (sq_check_save_extension($message->entities[$i])) {
+                   $ret = $message->entities[$i]->entity_id;
+               } else {
+                   $ret = '';
+               }
+           }
         }
     }
     return( $ret );
 }
 
+function sq_check_save_extension($message) {
+    $filename = $message->getFilename();
+    $ext = substr($filename, strrpos($filename,'.')+1);
+    $save_extensions = array('jpg','jpeg','gif','png','bmp');
+    return (in_array($ext, $save_extensions));
+}
+
+
 /**
  ** HTMLFILTER ROUTINES
  */
@@ -606,7 +652,9 @@ function find_ent_id( $id, $message ) {
  * @return           a string with the final tag representation.
  */
 function sq_tagprint($tagname, $attary, $tagtype){
-    $me = "sq_tagprint";
+    
+    $me = 'sq_tagprint';
+    
     if ($tagtype == 2){
         $fulltag = '</' . $tagname . '>';
     } else {
@@ -619,9 +667,9 @@ function sq_tagprint($tagname, $attary, $tagtype){
             $fulltag .= ' ' . join(" ", $atts);
         }
         if ($tagtype == 3){
-            $fulltag .= " /";
+            $fulltag .= ' /';
         }
-        $fulltag .= ">";
+        $fulltag .= '>';
     }
     return $fulltag;
 }
@@ -648,7 +696,7 @@ function sq_casenormalize(&$val){
  *                 non-whitespace char is located.
  */
 function sq_skipspace($body, $offset){
-    $me = "sq_skipspace";
+    $me = 'sq_skipspace';
     preg_match("/^(\s*)/s", substr($body, $offset), $matches);
     if (sizeof($matches{1})){
         $count = strlen($matches{1});
@@ -669,7 +717,7 @@ function sq_skipspace($body, $offset){
  *                 strlen($body) if needle wasn't found.
  */
 function sq_findnxstr($body, $offset, $needle){
-    $me = "sq_findnxstr";
+    $me = 'sq_findnxstr';
     $pos = strpos($body, $needle, $offset);
     if ($pos === FALSE){
         $pos = strlen($body);
@@ -691,7 +739,7 @@ function sq_findnxstr($body, $offset, $needle){
  *                 - string with whatever it is we matched
  */
 function sq_findnxreg($body, $offset, $reg){
-    $me = "sq_findnxreg";
+    $me = 'sq_findnxreg';
     $matches = Array();
     $retarr = Array();
     preg_match("%^(.*?)($reg)%s", substr($body, $offset), $matches);
@@ -720,7 +768,7 @@ function sq_findnxreg($body, $offset, $reg){
  *                 first three members will be false, if the tag is invalid.
  */
 function sq_getnxtag($body, $offset){
-    $me = "sq_getnxtag";
+    $me = 'sq_getnxtag';
     if ($offset > strlen($body)){
         return false;
     }
@@ -748,11 +796,11 @@ function sq_getnxtag($body, $offset){
      */
     $tagtype = false;
     switch (substr($body, $pos, 1)){
-    case "/":
+    case '/':
         $tagtype = 2;
         $pos++;
         break;
-    case "!":
+    case '!':
         /**
          * A comment or an SGML declaration.
          */
@@ -799,7 +847,7 @@ function sq_getnxtag($body, $offset){
      * Whatever else we find there indicates an invalid tag.
      */
     switch ($match){
-    case "/":
+    case '/':
         /**
          * This is an xhtml-style tag with a closing / at the
          * end, like so: <img src="blah"/>. Check if it's followed
@@ -813,7 +861,7 @@ function sq_getnxtag($body, $offset){
             $retary = Array(false, false, false, $lt, $gt);
             return $retary;
         }
-    case ">":
+    case '>':
         return Array($tagname, false, $tagtype, $lt, $pos);
         break;
     default:
@@ -901,7 +949,7 @@ function sq_getnxtag($body, $offset){
          *      anything else means the attribute is invalid.
          */
         switch($match){
-        case "/":
+        case '/':
             /**
              * This is an xhtml-style tag with a closing / at the
              * end, like so: <img src="blah"/>. Check if it's followed
@@ -915,7 +963,7 @@ function sq_getnxtag($body, $offset){
                 $retary = Array(false, false, false, $lt, $gt);
                 return $retary;
             }
-        case ">":
+        case '>':
             $attary{$attname} = '"yes"';
             return Array($tagname, $attary, $tagtype, $lt, $pos);
             break;
@@ -1004,7 +1052,7 @@ function sq_getnxtag($body, $offset){
  * @return           Translated value.
  */
 function sq_deent($attvalue){
-    $me="sq_deent";
+    $me = 'sq_deent';
     /**
      * See if we have to run the checks first. All entities must start
      * with "&".
@@ -1063,7 +1111,7 @@ function sq_fixatts($tagname,
                     $id,
                    $mailbox
                     ){
-    $me = "sq_fixatts";
+    $me = 'sq_fixatts';
     while (list($attname, $attvalue) = each($attary)){
         /**
          * See if this attribute should be removed.
@@ -1137,7 +1185,7 @@ function sq_fixatts($tagname,
  */
 function sq_fixstyle($message, $id, $content){
     global $view_unsafe_images;
-    $me = "sq_fixstyle";
+    $me = 'sq_fixstyle';
     /**
      * First look for general BODY style declaration, which would be
      * like so:
@@ -1199,9 +1247,15 @@ function sq_cid2http($message, $id, $cidurl, $mailbox){
     $quotchar = substr($cidurl, 0, 1);
     $cidurl = str_replace($quotchar, "", $cidurl);
     $cidurl = substr(trim($cidurl), 4);
-    $httpurl = $quotchar . "../src/download.php?absolute_dl=true&amp;" .
-        "passed_id=$id&amp;mailbox=" . urlencode($mailbox) .
-        "&amp;passed_ent_id=" . find_ent_id($cidurl, $message) . $quotchar;
+    $linkurl = find_ent_id($cidurl, $message);
+    /* in case of non-save cid links $httpurl should be replaced by a sort of
+       unsave link image */
+    $httpurl = '';
+    if ($linkurl) {
+        $httpurl = $quotchar . "../src/download.php?absolute_dl=true&amp;" .
+                   "passed_id=$id&amp;mailbox=" . urlencode($mailbox) .
+                   "&amp;ent_id=" . $linkurl . $quotchar;
+    }
     return $httpurl;
 }
 
@@ -1213,23 +1267,23 @@ function sq_cid2http($message, $id, $cidurl, $mailbox){
  * @return          a modified array of attributes to be set for <div>
  */
 function sq_body2div($attary){
-    $me = "sq_body2div";
-    $divattary = Array("class"=>"'bodyclass'");
-    $bgcolor="#ffffff";
-    $text="#000000";
-    $styledef="";
+    $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":
+            case 'background':
                 $styledef .= "background-image: url('$attvalue'); ";
                 break;
-            case "bgcolor":
+            case 'bgcolor':
                 $styledef .= "background-color: $attvalue; ";
                 break;
-            case "text":
+            case 'text':
                 $styledef .= "color: $attvalue; ";
             }
         }
@@ -1272,7 +1326,7 @@ function sq_sanitize($body,
                      $id,
                     $mailbox
                      ){
-    $me = "sq_sanitize";
+    $me = 'sq_sanitize';
     /**
      * Normalize rm_tags and rm_tags_with_content.
      */