Fixed on the fly decoding of base64 attachment. We need to do on the fly
authorstekkel <stekkel@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Sun, 2 May 2004 13:49:14 +0000 (13:49 +0000)
committerstekkel <stekkel@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Sun, 2 May 2004 13:49:14 +0000 (13:49 +0000)
decoding because otherwise we have to buffer entire attachments in memory
which will cause out of memory errors with large attachments.

The fix has to do with the grouping of bytes in pairs of 4 which represents
24 bits of data. If such group is splitted over 2 lines then on the fly
decoding went wrong. Now we count the pure base64 data (without \r\n, \r \n
and spaces), divide it by 4 and return incomplete pairs which get processed
the in the next loop.

git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@7343 7612ce4b-ef26-0410-bec9-ea0150e637f0

functions/imap_general.php
functions/mime.php

index 3c812805b4c31d0babc35bee1023fdba16be9f2d..abb2228b25f4a3a3199826d786c8cb2945cfff56 100755 (executable)
@@ -206,6 +206,7 @@ function sqimap_fread($imap_stream,$iSize,$filter=false,
     if ($iSize < $iBufferSize) {
         $iBufferSize = $iSize;
     }
+
     $iRetrieved = 0;
     $results = '';
     $sRead = $sReadRem = '';
@@ -226,19 +227,10 @@ function sqimap_fread($imap_stream,$iSize,$filter=false,
             $sRead = $sReadRem . $sRead;
             $sReadRem = '';
         }
-        if (substr($sRead,-1) !== "\n") {  
-            $i = strrpos($sRead,"\n");
-            if ($i !== false && $iRetrieved<$iSize) {
-                ++$i;
-                $sReadRem = substr($sRead,$i);
-                $sRead = substr($sRead,0,$i);
-            } else if ($iLength && $iRetrieved<$iSize) { // linelength > received buffer
-                $sReadRem = $sRead;
-                $sRead = '';
-            }
-        } 
+
         if ($filter && $sRead) {
-           $filter($sRead);
+           // in case the filter is base64 decoding we return a remainder 
+           $sReadRem = $filter($sRead);
         }
         if ($outputstream && $sRead) {
            if (is_resource($outputstream)) {
@@ -256,6 +248,7 @@ function sqimap_fread($imap_stream,$iSize,$filter=false,
     return $results;       
 }        
 
+
 /**
  * Obsolete function, inform plugins that use it
  * @deprecated use sqimap_run_command or sqimap_run_command_list instead
index c2bfcf2b6eb47f494df1b404760195ec1378c246..07cfe443d988e09c0e762165b743dc408ee58d3c 100644 (file)
@@ -550,10 +550,30 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) {
 }
 
 function sqimap_base64_decode(&$string) {
-    $string = str_replace("\r\n", "\n", $string);
+
+    // base64 enoded data goes in pairs of 4 bytes. To achieve on the
+    // fly decoding (to reduce memory usage) you have to check if the
+    // data has incomplete pairs
+
+    // remove the noise in order to check if the 4 bytes pairs are complete
+    $string = str_replace(array("\r\n","\n", "\r", " "),array('','','',''),$string);
+
+    $sStringRem = '';    
+    $iMod = strlen($string) % 4;
+    if ($iMod) {
+        $sStringRem = substr($string,-$iMod);
+        // check if $sStringRem contains padding characters
+        if (substr($sStringRem,-1) != '=') {
+            $string = substr($string,0,-$iMod);
+        } else {
+            $sStringRem = '';
+        }
+    }
     $string = base64_decode($string);
+    return $sStringRem;
 }
 
+
 /* This function decodes the body depending on the encoding type. */
 function decodeBody($body, $encoding) {
     global $show_html_default;