0

I have a MIME-encoded messages (in Maildir), that are having both base64-encoded headers (solved by lurking for related question ( Decode an UTF8 email header ), decode('MIME-Header', $val), main body in plain text and a text/plain base64 encoded data in the body;

It is said, that base64 data is encoded in utf-8. However, when I do:

use MIME::Base4;
..
$decoded = decode_base64($block_from_line_array); # MIME body extracted from message's
$msgtext .= $decoded;
..
print decode('utf-8', $msgtext);

It seems that the block is decoded incorrectly.

print decode('utf-8', $msgtext); works ok, when message body is in utf-8

Attach:

X-Priority: 3
X-Mailer: PHPMailer (phpmailer.sourceforge.net) [version 2.0.4]
X-Mailer: http://www.we.praise.buggy.php.scripts.what.we.do.when.we.dont.do.us
X-MessageID: 140
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="b1_16819d4d69564bfc0185ed5b9508ad31"

<Here the body begins -- mhambra>
--b1_16819d4d69564bfc0185ed5b9508ad31
Content-Type: text/plain; charset = "utf-8"
Content-Transfer-Encoding: base64
<MIME BLOCK>

Message is known to be displayed correctly in GMail.

Community
  • 1
  • 1
kagali-san
  • 2,964
  • 7
  • 48
  • 87

3 Answers3

1

FWIW Email::MIME seemed fragile for me on some example emails I was testing. Email::Parser worked better for me trying to extract segments of text/html or text/plain that might be in base64 (and usually had transfer-encoding base64 / utf-8

use MIME::Parser;
use MIME::Base64;

sub flatten_parts {
    my ($mimePart, $fh) = @_;
    $fh or $fh = select;
    my $part;
    no strict 'refs';
    if($mimePart->mime_type =~ /text\/(plain|html)/i){
        my $base64=join('',@{$mimePart->body}); # This will be the base64 we're after.
        my $encoding = $mimePart->head->mime_encoding;
        if($encoding eq 'base64'){
                my $plainContent=MIME::Base64::decode_base64($base64);
                print $plainContent;
        }
    }   
    ### walk the parts:
    my @parts = $mimePart->parts;
    foreach $part (@parts) {
        flatten_parts($part, $fh);
    }
}
### Create a new parser object:
our $parser = new MIME::Parser;
### Parse an input filehandle:
$entity = $parser->parse(\*STDIN);
flatten_parts($entity);
pacifist
  • 712
  • 4
  • 13
0

Use a module like Email::MIME to do the hard work.

use strict;
use warnings;
use Email::MIME;

my $msg = Email::MIME->new($message_text);
print $msg->body;
mscha
  • 6,509
  • 3
  • 24
  • 40
0

Sadly, if you happen to write a Greek lambda in an UTF8 formatted mail, MIME::Parser barfs, and there seems to be no known workaround — not even editing all the *.pm files, adding use utf8;, etc.

Try opening a new message in Thunderbird, attach some files, write that unicode character in the body and save it as a .eml file. MIME::Parser will throw an error.

See also CPAN Bug #105377.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93