From 48500e5b81925ec89af420fa9ab5c9b2d365dda0 Mon Sep 17 00:00:00 2001 From: "karl%kornel.name" <> Date: Sat, 24 Dec 2005 01:21:00 +0000 Subject: Bug 304885: UTF-8 encoding mangles multipart messages, breaks whine emails - Patch by A. Karl Kornel r=glob a=justdave --- Bugzilla/BugMail.pm | 66 ++++++++++++++++++++++++++++++++++------------------- whine.pl | 2 +- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index 31d151112..982bf6c04 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -633,7 +633,7 @@ sub MessageToMTA { my $headers; if (Param('utf8') and (!is_7bit_clean($header) or !is_7bit_clean($body))) { - ($headers, $body) = encode_message($header, $body); + ($headers, $body) = encode_message($msg); } else { my @header_lines = split(/\n/, $header); $headers = new Mail::Header \@header_lines, Modify => 0; @@ -697,21 +697,26 @@ sub encode_qp_words { } sub encode_message { - my ($header, $body) = @_; - - # read header into MIME::Entity + my ($msg) = @_; my $parser = MIME::Parser->new; $parser->output_to_core(1); $parser->tmp_to_core(1); - my $entity = $parser->parse_data($header); - my $head = $entity->head; + my $entity = $parser->parse_data($msg); + $entity = encode_message_entity($entity); + + my @header_lines = split(/\n/, $entity->header_as_string); + my $head = new Mail::Header \@header_lines, Modify => 0; + + my $body = $entity->body_as_string; + + return ($head, $body); +} - # set charset to UTF-8 +sub encode_message_entity { + my ($entity) = @_; - $head->mime_attr('Content-Type' => 'text/plain') - unless defined $head->mime_attr('content-type'); - $head->mime_attr('Content-Type.charset' => 'UTF-8'); + my $head = $entity->head; # encode the subject @@ -745,23 +750,38 @@ sub encode_message { # process the body - if (!is_7bit_clean($body)) { - # count number of 7-bit chars, and use quoted-printable if more - # than half the message is 7-bit clean - my $count = ($body =~ tr/\x20-\x7E\x0A\x0D//); - if ($count > length($body) / 2) { - $head->mime_attr('Content-Transfer-Encoding' => 'quoted-printable'); - $body = encode_qp($body); - } else { - $head->mime_attr('Content-Transfer-Encoding' => 'base64'); - $body = encode_base64($body); + if (scalar($entity->parts)) { + my $newparts = []; + foreach my $part ($entity->parts) { + my $newpart = encode_message_entity($part); + push @$newparts, $newpart; + } + $entity->parts($newparts); + } + else { + # Extract the body from the entity, for examination + # At this point, we can rely on MIME::Tools to do our encoding for us! + my $bodyhandle = $entity->bodyhandle; + my $body = $bodyhandle->as_string; + if (!is_7bit_clean($body)) { + # count number of 7-bit chars, and use quoted-printable if more + # than half the message is 7-bit clean + my $count = ($body =~ tr/\x20-\x7E\x0A\x0D//); + if ($count > length($body) / 2) { + $head->mime_attr('Content-Transfer-Encoding' => 'quoted-printable'); + } else { + $head->mime_attr('Content-Transfer-Encoding' => 'base64'); + } } + + # Set the content/type and charset of the part, if not set + $head->mime_attr('Content-Type' => 'text/plain') + unless defined $head->mime_attr('content-type'); + $head->mime_attr('Content-Type.charset' => 'UTF-8'); } - # done - $head->fold(75); - return ($head, $body); + return $entity; } # Send the login name and password of the newly created account to the user. diff --git a/whine.pl b/whine.pl index 0c8815368..b001957dd 100755 --- a/whine.pl +++ b/whine.pl @@ -404,7 +404,7 @@ sub mail { # now produce a ready-to-mail mime-encoded message - $args->{'boundary'} = "-----=====-----" . $$ . "--" . time() . "-----"; + $args->{'boundary'} = "----------" . $$ . "--" . time() . "-----"; $template->process("whine/multipart-mime.txt.tmpl", $args, \$msg) or die($template->error()); -- cgit v1.2.3-24-g4f1b