Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ivan Ivlev
bugzilla
Commits
948b5806
Commit
948b5806
authored
Oct 23, 2015
by
Frédéric Buclin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 714724: Correctly encode emails as quoted-printable
r=dkl a=sgreen
parent
3b29cba4
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
158 additions
and
142 deletions
+158
-142
BugMail.pm
Bugzilla/BugMail.pm
+14
-9
MIME.pm
Bugzilla/MIME.pm
+132
-0
Mailer.pm
Bugzilla/Mailer.pm
+2
-71
011pod.t
t/011pod.t
+1
-0
header.txt.tmpl
template/en/default/whine/header.txt.tmpl
+0
-20
whine.pl
whine.pl
+9
-42
No files found.
Bugzilla/BugMail.pm
View file @
948b5806
...
...
@@ -19,6 +19,7 @@ use Bugzilla::Bug;
use
Bugzilla::
Comment
;
use
Bugzilla::
Mailer
;
use
Bugzilla::
Hook
;
use
Bugzilla::
MIME
;
use
Date::
Parse
;
use
Date::
Format
;
...
...
@@ -435,6 +436,7 @@ sub _generate_bugmail {
my
$user
=
$vars
->
{
to_user
};
my
$template
=
Bugzilla
->
template_inner
(
$user
->
setting
(
'lang'
));
my
(
$msg_text
,
$msg_html
,
$msg_header
);
state
$use_utf8
=
Bugzilla
->
params
->
{
'utf8'
};
$template
->
process
(
"email/bugmail-header.txt.tmpl"
,
$vars
,
\
$msg_header
)
||
ThrowTemplateError
(
$template
->
error
());
...
...
@@ -442,32 +444,35 @@ sub _generate_bugmail {
||
ThrowTemplateError
(
$template
->
error
());
my
@parts
=
(
Email
::
MIME
->
create
(
Bugzilla
::
MIME
->
create
(
attributes
=>
{
content_type
=>
"text/plain"
,
content_type
=>
'text/plain'
,
charset
=>
$use_utf8
?
'UTF-8'
:
'iso-8859-1'
,
encoding
=>
'quoted-printable'
,
},
body
=>
$msg_text
,
body
_str
=>
$msg_text
,
)
);
if
(
$user
->
setting
(
'email_format'
)
eq
'html'
)
{
$template
->
process
(
"email/bugmail.html.tmpl"
,
$vars
,
\
$msg_html
)
||
ThrowTemplateError
(
$template
->
error
());
push
@parts
,
Email
::
MIME
->
create
(
push
@parts
,
Bugzilla
::
MIME
->
create
(
attributes
=>
{
content_type
=>
"text/html"
,
content_type
=>
'text/html'
,
charset
=>
$use_utf8
?
'UTF-8'
:
'iso-8859-1'
,
encoding
=>
'quoted-printable'
,
},
body
=>
$msg_html
,
body
_str
=>
$msg_html
,
);
}
# TT trims the trailing newline, and threadingmarker may be ignored.
my
$email
=
new
Email::
MIME
(
"$msg_header\n"
);
my
$email
=
Bugzilla::
MIME
->
new
(
$msg_header
);
if
(
scalar
(
@parts
)
==
1
)
{
$email
->
content_type_set
(
$parts
[
0
]
->
content_type
);
}
else
{
$email
->
content_type_set
(
'multipart/alternative'
);
# Some mail clients need same encoding for each part, even empty ones.
$email
->
charset_set
(
'UTF-8'
)
if
Bugzilla
->
params
->
{
'utf8'
}
;
$email
->
charset_set
(
'UTF-8'
)
if
$use_utf8
;
}
$email
->
parts_set
(
\
@parts
);
return
$email
;
...
...
Bugzilla/MIME.pm
0 → 100644
View file @
948b5806
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
package
Bugzilla::
MIME
;
use
5.10.1
;
use
strict
;
use
warnings
;
use
parent
qw(Email::MIME)
;
use
Encode
qw(encode)
;
use
Encode::MIME::
Header
;
sub
new
{
my
(
$class
,
$msg
)
=
@_
;
state
$use_utf8
=
Bugzilla
->
params
->
{
'utf8'
};
# Template-Toolkit trims trailing newlines, which is problematic when
# parsing headers.
$msg
=~
s/\n*$/\n/
;
# Because the encoding headers are not present in our email templates, we
# need to treat them as binary UTF-8 when parsing.
my
(
$in_header
,
$has_type
,
$has_encoding
,
$has_body
)
=
(
1
);
foreach
my
$line
(
split
(
/\n/
,
$msg
))
{
if
(
$line
eq
''
)
{
$in_header
=
0
;
next
;
}
if
(
!
$in_header
)
{
$has_body
=
1
;
last
;
}
$has_type
=
1
if
$line
=~
/^Content-Type:/i
;
$has_encoding
=
1
if
$line
=~
/^Content-Transfer-Encoding:/i
;
}
if
(
$has_body
)
{
if
(
!
$has_type
&&
$use_utf8
)
{
$msg
=
qq#Content-Type: text/plain; charset="UTF-8"\n#
.
$msg
;
}
if
(
!
$has_encoding
)
{
$msg
=
qq#Content-Transfer-Encoding: binary\n#
.
$msg
;
}
}
if
(
$use_utf8
&&
utf8::
is_utf8
(
$msg
))
{
utf8::
encode
(
$msg
);
}
# RFC 2822 requires us to have CRLF for our line endings and
# Email::MIME doesn't do this for us. We use \015 (CR) and \012 (LF)
# directly because Perl translates "\n" depending on what platform
# you're running on. See http://perldoc.perl.org/perlport.html#Newlines
$msg
=~
s/(?:\015+)?\012/\015\012/msg
;
return
$class
->
SUPER::
new
(
$msg
);
}
sub
as_string
{
my
$self
=
shift
;
state
$use_utf8
=
Bugzilla
->
params
->
{
'utf8'
};
# We add this header to uniquely identify all email that we
# send as coming from this Bugzilla installation.
#
# We don't use correct_urlbase, because we want this URL to
# *always* be the same for this Bugzilla, in every email,
# even if the admin changes the "ssl_redirect" parameter some day.
$self
->
header_set
(
'X-Bugzilla-URL'
,
Bugzilla
->
params
->
{
'urlbase'
});
# We add this header to mark the mail as "auto-generated" and
# thus to hopefully avoid auto replies.
$self
->
header_set
(
'Auto-Submitted'
,
'auto-generated'
);
# MIME-Version must be set otherwise some mailsystems ignore the charset
$self
->
header_set
(
'MIME-Version'
,
'1.0'
)
if
!
$self
->
header
(
'MIME-Version'
);
# Encode the headers correctly in quoted-printable
foreach
my
$header
(
$self
->
header_names
)
{
my
@values
=
$self
->
header
(
$header
);
# We don't recode headers that happen multiple times.
next
if
scalar
(
@values
)
>
1
;
if
(
my
$value
=
$values
[
0
])
{
utf8::
decode
(
$value
)
unless
$use_utf8
&&
utf8::
is_utf8
(
$value
);
# avoid excessive line wrapping done by Encode.
local
$
Encode::
Encoding
{
'MIME-Q'
}
->
{
'bpl'
}
=
998
;
my
$encoded
=
encode
(
'MIME-Q'
,
$value
);
$self
->
header_set
(
$header
,
$encoded
);
}
}
# Ensure the character-set and encoding is set correctly on single part
# emails. Multipart emails should have these already set when the parts
# are assembled.
if
(
scalar
(
$self
->
parts
)
==
1
)
{
$self
->
charset_set
(
'UTF-8'
)
if
$use_utf8
;
$self
->
encoding_set
(
'quoted-printable'
);
}
# Ensure we always return the encoded string
my
$value
=
$self
->
SUPER::
as_string
();
if
(
$use_utf8
&&
utf8::
is_utf8
(
$value
))
{
utf8::
encode
(
$value
);
}
return
$value
;
}
1
;
__END__
=head1 NAME
Bugzilla::MIME - Wrapper around Email::MIME for unifying MIME related
workarounds.
=head1 SYNOPSIS
use Bugzilla::MIME;
my $email = Bugzilla::MIME->new($message);
=head1 DESCRIPTION
Bugzilla::MIME subclasses Email::MIME and performs various fixes when parsing
and generating email.
Bugzilla/Mailer.pm
View file @
948b5806
...
...
@@ -17,13 +17,11 @@ use parent qw(Exporter);
use
Bugzilla::
Constants
;
use
Bugzilla::
Error
;
use
Bugzilla::
Hook
;
use
Bugzilla::
MIME
;
use
Bugzilla::
Util
;
use
Date::
Format
qw(time2str)
;
use
Encode
qw(encode)
;
use
Encode::MIME::
Header
;
use
Email::
MIME
;
use
Email::Sender::
Simple
qw(sendmail)
;
use
Email::Sender::Transport::SMTP::
Persistent
;
use
Bugzilla::Sender::Transport::
Sendmail
;
...
...
@@ -43,18 +41,7 @@ sub MessageToMTA {
my
$dbh
=
Bugzilla
->
dbh
;
my
$email
;
if
(
ref
$msg
)
{
$email
=
$msg
;
}
else
{
# RFC 2822 requires us to have CRLF for our line endings and
# Email::MIME doesn't do this for us. We use \015 (CR) and \012 (LF)
# directly because Perl translates "\n" depending on what platform
# you're running on. See http://perldoc.perl.org/perlport.html#Newlines
$msg
=~
s/(?:\015+)?\012/\015\012/msg
;
$email
=
new
Email::
MIME
(
$msg
);
}
my
$email
=
ref
(
$msg
)
?
$msg
:
Bugzilla::
MIME
->
new
(
$msg
);
# If we're called from within a transaction, we don't want to send the
# email immediately, in case the transaction is rolled back. Instead we
...
...
@@ -71,39 +58,6 @@ sub MessageToMTA {
return
;
}
# We add this header to uniquely identify all email that we
# send as coming from this Bugzilla installation.
#
# We don't use correct_urlbase, because we want this URL to
# *always* be the same for this Bugzilla, in every email,
# even if the admin changes the "ssl_redirect" parameter some day.
$email
->
header_set
(
'X-Bugzilla-URL'
,
Bugzilla
->
params
->
{
'urlbase'
});
# We add this header to mark the mail as "auto-generated" and
# thus to hopefully avoid auto replies.
$email
->
header_set
(
'Auto-Submitted'
,
'auto-generated'
);
# MIME-Version must be set otherwise some mailsystems ignore the charset
$email
->
header_set
(
'MIME-Version'
,
'1.0'
)
if
!
$email
->
header
(
'MIME-Version'
);
# Encode the headers correctly in quoted-printable
foreach
my
$header
(
$email
->
header_names
)
{
my
@values
=
$email
->
header
(
$header
);
# We don't recode headers that happen multiple times.
next
if
scalar
(
@values
)
>
1
;
if
(
my
$value
=
$values
[
0
])
{
if
(
Bugzilla
->
params
->
{
'utf8'
}
&&
!
utf8::
is_utf8
(
$value
))
{
utf8::
decode
(
$value
);
}
# avoid excessive line wrapping done by Encode.
local
$
Encode::
Encoding
{
'MIME-Q'
}
->
{
'bpl'
}
=
998
;
my
$encoded
=
encode
(
'MIME-Q'
,
$value
);
$email
->
header_set
(
$header
,
$encoded
);
}
}
my
$from
=
$email
->
header
(
'From'
);
my
$hostname
;
...
...
@@ -148,29 +102,6 @@ sub MessageToMTA {
return
if
$email
->
header
(
'to'
)
eq
''
;
$email
->
walk_parts
(
sub
{
my
(
$part
)
=
@_
;
return
if
$part
->
parts
>
1
;
# Top-level
my
$content_type
=
$part
->
content_type
||
''
;
$content_type
=~
/charset=['"](.+)['"]/
;
# If no charset is defined or is the default us-ascii,
# then we encode the email to UTF-8 if Bugzilla has utf8 enabled.
# XXX - This is a hack to workaround bug 723944.
if
(
!
$1
||
$1
eq
'us-ascii'
)
{
my
$body
=
$part
->
body
;
if
(
Bugzilla
->
params
->
{
'utf8'
})
{
$part
->
charset_set
(
'UTF-8'
);
# encoding_set works only with bytes, not with utf8 strings.
my
$raw
=
$part
->
body_raw
;
if
(
utf8::
is_utf8
(
$raw
))
{
utf8::
encode
(
$raw
);
$part
->
body_set
(
$raw
);
}
}
$part
->
encoding_set
(
'quoted-printable'
)
if
!
is_7bit_clean
(
$body
);
}
});
if
(
$method
eq
"Test"
)
{
my
$filename
=
bz_locations
()
->
{
'datadir'
}
.
'/mailer.testfile'
;
open
TESTFILE
,
'>>'
,
$filename
;
...
...
t/011pod.t
View file @
948b5806
...
...
@@ -35,6 +35,7 @@ use constant SUB_WHITELIST => (
'Bugzilla::JobQueue' => qr/(?:^work_once|work_until_done|subprocess_worker)$/,
'Bugzilla::Search' => qr/^SPECIAL_PARSING$/,
'Bugzilla::Template' => qr/^field_name$/,
'Bugzilla::MIME' => qr/^as_string$/,
);
# These modules do not need to be documented, generally because they
...
...
template/en/default/whine/
multipart-mime
.txt.tmpl
→
template/en/default/whine/
header
.txt.tmpl
View file @
948b5806
...
...
@@ -8,10 +8,6 @@
[%# INTERFACE:
# subject: subject line of message
# alternatives: array of hashes containing:
# type: MIME type
# content: verbatim content
# boundary: a string that has been generated to be a unique boundary
# recipient: user object for the intended recipient of the message
# from: Bugzilla system email address
#%]
...
...
@@ -19,21 +15,5 @@
From: [% from %]
To: [% recipient.email %]
Subject: [[% terms.Bugzilla %]] [% subject %]
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="[% boundary %]"
X-Bugzilla-Type: whine
This is a MIME multipart message. It is possible that your mail program
doesn't quite handle these properly. Some or all of the information in this
message may be unreadable.
[% FOREACH part=alternatives %]
--[% boundary %]
Content-type: [% part.type +%]
[%+ part.content %]
[%+ END %]
--[% boundary %]--
whine.pl
View file @
948b5806
...
...
@@ -346,53 +346,20 @@ while (my $event = get_next_event) {
# - subject Subject line for the message
# - recipient user object for the recipient
# - author user object of the person who created the whine event
#
# In addition, mail adds two more fields to $args:
# - alternatives array of hashes defining mime multipart types and contents
# - boundary a MIME boundary generated using the process id and time
#
sub
mail
{
my
$args
=
shift
;
my
$addressee
=
$args
->
{
recipient
};
# Don't send mail to someone whose bugmail notification is disabled.
return
if
$addressee
->
email_disabled
;
my
$template
=
Bugzilla
->
template_inner
(
$addressee
->
setting
(
'lang'
));
my
$msg
=
''
;
# it's a temporary variable to hold the template output
$args
->
{
'alternatives'
}
||=
[]
;
# put together the different multipart mime segments
return
if
$args
->
{
recipient
}
->
email_disabled
;
$
template
->
process
(
"whine/mail.txt.tmpl"
,
$args
,
\
$msg
)
or
die
(
$template
->
error
());
push
@
{
$args
->
{
'alternatives'
}}
,
$
args
->
{
to_user
}
=
$args
->
{
recipient
};
MessageToMTA
(
generate_email
(
$args
,
{
'content'
=>
$msg
,
'type'
=>
'text/plain'
,
};
$msg
=
''
;
$template
->
process
(
"whine/mail.html.tmpl"
,
$args
,
\
$msg
)
or
die
(
$template
->
error
());
push
@
{
$args
->
{
'alternatives'
}},
{
'content'
=>
$msg
,
'type'
=>
'text/html'
,
};
$msg
=
''
;
# now produce a ready-to-mail mime-encoded message
$args
->
{
'boundary'
}
=
"----------"
.
$$
.
"--"
.
time
()
.
"-----"
;
$template
->
process
(
"whine/multipart-mime.txt.tmpl"
,
$args
,
\
$msg
)
or
die
(
$template
->
error
());
MessageToMTA
(
$msg
);
delete
$args
->
{
'boundary'
};
delete
$args
->
{
'alternatives'
};
header
=>
'whine/header.txt.tmpl'
,
text
=>
'whine/mail.txt.tmpl'
,
html
=>
'whine/mail.html.tmpl'
,
}
));
}
# run_queries runs all of the queries associated with a schedule ID, adding
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment