summaryrefslogtreecommitdiffstats
path: root/attachment.cgi
diff options
context:
space:
mode:
authorDylan Hardison <dylan@mozilla.com>2016-07-13 02:51:17 +0200
committerDylan Hardison <dylan@mozilla.com>2016-07-13 02:51:17 +0200
commit149769378a6ffc3bf4407866d2ccb23296ddbc23 (patch)
treee847cdc3185aafb8dd1fd7debd8c0a385ab545dd /attachment.cgi
parent876f5eb2e01a22cd53e77744afca56f38ebf0678 (diff)
downloadbugzilla-149769378a6ffc3bf4407866d2ccb23296ddbc23.tar.gz
bugzilla-149769378a6ffc3bf4407866d2ccb23296ddbc23.tar.xz
Bug 1285835 - BMO sending bogus Content-Disposition filenames when the filename is not ASCII
Diffstat (limited to 'attachment.cgi')
-rwxr-xr-xattachment.cgi35
1 files changed, 20 insertions, 15 deletions
diff --git a/attachment.cgi b/attachment.cgi
index 772674bfc..7f6353bdd 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -54,9 +54,11 @@ use Bugzilla::Token;
use Bugzilla::Keyword;
use Bugzilla::Hook;
-use Encode qw(encode find_encoding);
+use Encode qw(encode find_encoding from_to);
use URI;
use URI::QueryParam;
+use URI::Escape qw(uri_escape_utf8);
+use File::Basename qw(basename);
# For most scripts we don't make $cgi and $template global variables. But
# when preparing Bugzilla for mod_perl, this script used these
@@ -381,7 +383,7 @@ sub view {
# At this point, Bugzilla->login has been called if it had to.
my $contenttype = $attachment->contenttype;
- my $filename = $attachment->filename;
+ my $filename = basename($attachment->filename);
my $contenttype_override = 0;
# Bug 111522: allow overriding content-type manually in the posted form
@@ -397,18 +399,6 @@ sub view {
# BMO add a hook for github url redirection
Bugzilla::Hook::process('attachment_view', { attachment => $attachment });
- $filename =~ s/^.*[\/\\]//;
- # escape quotes and backslashes in the filename, per RFCs 2045/822
- $filename =~ s/\\/\\\\/g; # escape backslashes
- $filename =~ s/"/\\"/g; # escape quotes
-
- # Avoid line wrapping done by Encode, which we don't need for HTTP
- # headers. See discussion in bug 328628 for details.
- local $Encode::Encoding{'MIME-Q'}->{'bpl'} = 10000;
- $filename = encode('MIME-Q', $filename);
-
- my $disposition = Bugzilla->params->{'allow_attachment_display'} ? 'inline' : 'attachment';
-
my $do_redirect = 0;
Bugzilla::Hook::process('attachment_should_redirect_login', { do_redirect => \$do_redirect });
@@ -437,11 +427,26 @@ sub view {
}
Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get")
if Bugzilla->user->id;
+
+ my $disposition = Bugzilla->params->{'allow_attachment_display'} ? 'inline' : 'attachment';
+
+ my $ascii_filename = $filename;
+ utf8::encode($ascii_filename);
+ from_to($ascii_filename, 'UTF-8', 'ascii');
+ $ascii_filename =~ s/(["\\])/\\$1/g;
+ my $qfilename = qq{"$filename"};
+ my $ufilename = qq{UTF-8''} . uri_escape_utf8($filename);
+
+ my $filenames = "filename=$qfilename";
+ if ($ascii_filename ne $filename) {
+ $filenames .= "; filename*=$ufilename";
+ }
+
# IE8 and older do not support RFC 6266. So for these old browsers
# we still pass the old 'filename' attribute. Modern browsers will
# automatically pick the new 'filename*' attribute.
print $cgi->header(-type=> $contenttype,
- -content_disposition=> "$disposition; filename=\"$filename\"; filename*=UTF-8''$filename",
+ -content_disposition=> "$disposition; $filenames",
-content_length => $attachment->datasize);
disable_utf8();
print $attachment->data;