rjbs / Email-MIME

perl library for parsing MIME messages
20 stars 30 forks source link

One case of a "Use of uninitialized value" in the Header.pm (line 126) #44

Closed ventz closed 7 years ago

ventz commented 7 years ago

Hi,

Running into a potential bug around the header handling.

I have an email which has been forwarded, and when the forwarded body is extracted with:

# $mail_in = the forwarded email "as is"
my $mail = Email::MIME->new($mail_in);

my $body; for my $subpart ($part->parts) { $body .= $subpart->body; }

for my $part ($mail->parts) {
if ($part->content_type =~ m!text/plain! || $part->content_type =~ m!text/html! || $part->content_type eq '') {
    ... # not relevant, but for context ...
}
elsif ($part->content_type =~ m!multipart/alternative!) {

    # Now here -> when I try to pull the $body to extract the headers from the forwarded email:
    my $msg = Email::MIME->new($body);
    # ^ it produces the error (see next code block bellow for "Error:")
    # This works on multiple emails, except this one here (see the last code block for "Original Email")
}

When I create a new msg with:

my $msg = Email::MIME->new($data);

Error:

Use of uninitialized value in lc at /usr/local/share/perl/5.14.2/Email/Simple/Header.pm line 126, <STDIN> line 300.
Use of uninitialized value in lc at /usr/local/share/perl/5.14.2/Email/Simple/Header.pm line 126, <STDIN> line 300.

The same happens then for each header. Although extracting the $msg->body_raw works fine.

Original Email (the FW part, minus headers from FW) - the "$body" that becomes $msg:

https://pastebin.com/6JG6MnkV
pali commented 7 years ago

Can you provide exact content of $data? I have not fully understood what you mean and when I tried to put above pastebin output into $data for Email::MIME->new there was no warning at all.

ventz commented 7 years ago

@pali Is there a way I can provide you the full email privately?

ventz commented 7 years ago

The format btw:

  I     1 <no description>                                                                                   [multipa/alternativ, 7bit, 13K] 
  I     2 ├─><no description>                                                                              [text/plain, base64, utf-8, 0.9K] 
  I     3 └─><no description>                                                                                [text/html, base64, utf-8, 12K] 
  I     4 image002.png                                                                                             [image/png, base64, 3.9K] 

And I am trying to extract these:

From: Apple.mx [mailto:info@csgna.com]                                                                                                       
Sent: Wednesday, July 26, 2017 5:42 AM                                                                                                       
To: redacted#1                                                                                         
Subject: Tu recibo no #9590343       

From the full email being:

Date: Wed, 26 Jul 2017 12:43:19 +0000                                                                                                        
From: redacted#1                                                                    
To: redacted#2                                                                                       
CC: redacted#3                          
Subject: FW: Tu recibo no #9590343                                                                                                           

[-- Attachment #1 --]                                                                                                                        
[-- Type: multipart/alternative, Encoding: 7bit, Size: 13K --]                                                                               

From: Apple.mx [mailto:info@csgna.com]                                                                                                       
Sent: Wednesday, July 26, 2017 5:42 AM                                                                                                       
To: redacted#1                                                                                          
Subject: Tu recibo no #9590343                                                                                                               

[Text Box: Brian Tracy's  Success Newsletter  For Personal Achievement and Time Management]                                                  

Estimado Cliente,                                                                                                                            

Su cuenta ID ha sido usada para adquirir album Enrique Iglesias ($4,76) desde iTunes Store en un                                             
dispositivo que no tenemos asociado a usted.                                                                                                 

Si usted realzo esta transaccion, Usted puede descartar este correo.                                                                         

Si usted no realizo esta transaccion, Por favor dirijase a http:/apple.com/support/cancel-691500248<http://www.sekerpinarcicek.net/z.htm>    
+Para cancelar la transaccion.                                                                                                               

Apple !,                                                                                                                                     

Itunes                    
pali commented 7 years ago

@ventz I already sent you private email. Without original content of $data which you pass into Email::MIME->new I'm unable to debug this issue.

ventz commented 7 years ago

@pali I sent you an email last week (Mon, Jul 31, 2017 at 11:21 AM EDT) with the original compressed (zip). Let me know if you didn't get it - I'll send it again.

pali commented 7 years ago

I got that problematic email from @ventz, but I'm not able to reproduce above uninitialized warning. I just put content of that email into Email::MIME->new($data);. Also that problematic email had mbox From line which needs to be stripped before passing into Email::MIME.

ventz commented 7 years ago

@pali When testing by hand, I am just cat-ing the email into the script and slurping it with:

my $mail_in = ''; while(<STDIN>) { $mail_in .= $_; }

In the original code (first post here), in this part:

elsif ($part->content_type =~ m!multipart/alternative!) {

    # Now here -> when I try to pull the $body to extract the headers from the forwarded email:
    my $msg = Email::MIME->new($body);
    # ^ it produces the error (see next code block bellow for "Error:")
    # This works on multiple emails, except this one here (see the last code block for "Original Email")
}

I can't take $msg and extract any headers from it (from, subject, etc)

pali commented 7 years ago

Ok, I looked into first post again and code there specified is incorrect. In forth line you are using variable $part which was not defined yet. Also your problematic part depends on variable $body which is created by that problematic code where $part was not defined yet. Can you please fix your testing code? As I really do not know what should I test and debug...

ventz commented 7 years ago

@pali That's just because I pulled it out of the prod code.

The $body line:

my $body; for my $subpart ($part->parts) { $body .= $subpart->body; }

Should be in the for loop:

for my $part ($mail->parts) {
my $body...
# Then there is:
if ($part->content_type =~ m!multipart/alternative!) {
            &find_all_fwd_headers(\$body);
        }
}

And then the "find_all_fwd_headers" is:

my $msg = Email::MIME->new($data);
my $data = shift; $data = $$data;
        $headers{'forwarded-date'} = $msg->header('Date') || $msg->header('Sent');
        $headers{'forwarded-from'} = $msg->header('From');
        $headers{'forwarded-to'} = $msg->header('To');
        $headers{'forwarded-cc'} = $msg->header('Cc');
        $subject = $msg->header('Subject');

There is a lot more code (hundreds of lines just around debugging), but this is the core part around mail, and I am trying to provide a clean example without making it harder.

Thanks.

pali commented 7 years ago

So here is my code for testing:

use strict;
use warnings;
use Email::MIME;
open my $fh, "broken" or die;
my $data = join("", <$fh>);
my $email = Email::MIME->new($data);
for my $part ($email->parts) {
  next unless $part->content_type =~ m!multipart/alternative!;
  my $body;
  for my $subpart ($part->parts) { $body .= $subpart->body; }
  my $email2 = Email::MIME->new($body);
}

But I still have not got that warning...

ventz commented 7 years ago

I am getting this when I run the block above:

# ./t.pl 
Use of uninitialized value in lc at /usr/local/share/perl/5.14.2/Email/Simple/Header.pm line 126, <$fh> line 300.
Use of uninitialized value in lc at /usr/local/share/perl/5.14.2/Email/Simple/Header.pm line 126, <$fh> line 300.

Specifically, the "my $email2" line is causing it. If you comment it out, the error goes away.

pali commented 7 years ago

Then please recheck that you have last version of Email::MIME, Email::Simple and other dependencies.

I tested it with perl 5.14.2 too and no warning there.

ventz commented 7 years ago

@pali I just built the package from CPAN:

 RJBS/Email-MIME-1.945.tar.gz
  /usr/bin/make test -- OK
Running make install
Installing /usr/local/share/perl/5.14.2/Email/MIME.pm
Installing /usr/local/share/perl/5.14.2/Email/MIME/Header.pm

No errors.

It looks like the default packaged one (in Ubuntu) has the issue.

pali commented 7 years ago

So we can close this issue as already fixed in last version...

ventz commented 7 years ago

Definitely. Closing now. Thanks for your help/debugging.