icaine / php-mime-mail-parser

Automatically exported from code.google.com/p/php-mime-mail-parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Small attachments are not parsed correctly

GoogleCodeExporter opened this issue · comments

What steps will reproduce the problem?
1. A mail with small attachments (< 2028 bytes)

Around line 405 in MimeMailParser.class.php:
if (($written+$write < $len )) {

I believe it should be:
if ($len - $written < $write) {

Original issue reported on code.google.com by jma...@gmail.com on 19 Jan 2010 at 7:56

Please ignore above fix, it causes problems with larger attachments.

I ended up changing it to read all data at once.

...
$len = $end-$start;

$part = fread($this->stream, $len);
fwrite($temp_fp, $this->decode($part, $encoding));

} else if ($this->data) {
...

Original comment by jma...@gmail.com on 19 Jan 2010 at 8:31

I think in Method getAttachmentStream from MimeMailParser.class.php it should 
be:

line 399:
old:
if (($written+$write < $len )) {
new:
if (($written+$write > $len )) {

Original comment by palvoel...@gmail.com on 27 Aug 2010 at 3:40

I believe palvoelgyi is right. 
Jmared, could you test that with your attachments and see if it works for you 
please?

I will commit the change if it is verified.

http://code.google.com/p/php-mime-mail-parser/source/browse/trunk/MimeMailParser
.class.php?r=16#399

PS: We need to read the data in chunks as some attachments may be larger then 
PHP memory limit. 

Original comment by buca...@gmail.com on 27 Aug 2010 at 4:45

  • Changed state: Started
Just noticed this was from Jan, will commit once I test this.

Original comment by buca...@gmail.com on 27 Aug 2010 at 4:46

Isn't there a double bug here? The modification above is in theory correct, it 
does what code structure intended to do.

But the problem is that you cannot call the decode() function for the chunks of 
file like this! I guess it almost always works if the encoding is 
quoted-printable. Could break if there happens to be a character encoding 
across the chunks. But for base64 encoding this fails probably in majority of 
the cases. 

The old version fails in a nice way, causing long (>2k) attachments to be 
handled in one chunk. Thus working properly with the decode function. The old 
version failed on attachments smaller than 2kB. 

The following is not a nice way of coding this, but this fix works for me. For 
both small and big attachments and for both quoted-printable and base64 encoded 
attachments. Changed the same part of code to read as:

                                while($written < $len) {
                                        $write = $len;
                                        $part = fread($this->stream, $write);
                                        fwrite($temp_fp, $this->decode($part, $encoding));
                                        $written += $write;
                                }

Pertti 

Original comment by info.fam...@gmail.com on 5 Nov 2010 at 4:27

I believe the stream filters should be used here when possible:

http://us3.php.net/manual/en/function.stream-get-filters.php

That way we can keep from saving the whole encoded data into a variable for 
decoding, which would not be efficient for large files. 


Original comment by buca...@gmail.com on 6 Nov 2010 at 5:16

  • Changed state: Accepted

I just spent a few hours figuring out why some attachments weren't being 
decoded correctly only to find out it had already been discussed here.

Maybe this should be changed so it reads the whole encoded data for now?  It's 
exactly what it's doing already anyway, except small attachments aren't decoded 
properly.  The entire while loop could just be replaced by something like:

    $part = fread($this->stream, $len);
    fwrite($temp_fp, $this->decode($part, $encoding));

It's a temporary fix, but it could save others from wasting time debugging the 
exact same problem.

-Adrian

Original comment by agpc...@gmail.com on 23 Feb 2012 at 7:54

Thank you Adrian. 

Original comment by m.michal...@gmail.com on 25 Mar 2013 at 12:41

The problem is easily fixed by replacing line 400
                $write = 2028;
with
                $write = ($len<2028)?$len:2028;



Original comment by eckhard....@arcor.de on 14 May 2013 at 6:13

[deleted comment]
This issue is reproduced, corrected and tested 
(https://github.com/eXorus/php-mime-mail-parser/issues/2)

You could use my fork if you want : 
https://github.com/eXorus/php-mime-mail-parser

Original comment by eXorus.m...@gmail.com on 28 Jul 2013 at 4:22