Skip to content

Commit

Permalink
Fix decoding of attachment names encoded using both RFC2231 and RFC20…
Browse files Browse the repository at this point in the history
…47 standards (#9725)
  • Loading branch information
alecpl committed Feb 2, 2025
1 parent fa1f3bd commit 41eaff2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
- Fix Oauth issues with use_secure_urls=true (#9722)
- Fix handling of binary mail parts (e.g. PDF) encoded with quoted-printable (#9728)
- Fix links in comments and config to https:// where available (#9759, #9756)
- Fix decoding of attachment names encoded using both RFC2231 and RFC2047 standards (#9725)

## Release 1.6.9

Expand Down
20 changes: 10 additions & 10 deletions program/lib/Roundcube/rcube_message_part.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,22 @@ public function normalize($headers = null)
$filename_mime = $this->headers['content-description'];
}

// decode filename
if (isset($filename_encoded)) {
// decode filename according to RFC 2231, Section 4
if (preg_match("/^([^']*)'[^']*'(.*)$/", $filename_encoded, $fmatches)) {
$filename_charset = $fmatches[1];
$filename_encoded = $fmatches[2];
}
// decode filename according to RFC 2231, Section 4
if (isset($filename_encoded) && preg_match("/^([^']*)'[^']*'(.*)$/", $filename_encoded, $fmatches)) {
$filename_charset = $fmatches[1];
$filename_encoded = $fmatches[2];

$this->filename = rawurldecode($filename_encoded);

if (!empty($filename_charset)) {
$this->filename = rcube_charset::convert($this->filename, $filename_charset);
}
} elseif (isset($filename_mime)) {
// Note: Do not use charset of part/message nor the default charset (#9376)
$this->filename = rcube_mime::decode_mime_string($filename_mime, false);
} else {
// Note: RFC2047 can appear inside RFC2231 formatted parameters too (#9725)
if (isset($filename_encoded) || isset($filename_mime)) {
// Note: Do not use charset of part/message nor the default charset (#9376)
$this->filename = rcube_mime::decode_mime_string($filename_encoded ?? $filename_mime, false);
}
}

// Workaround for invalid Content-Type (#6816)
Expand Down
21 changes: 21 additions & 0 deletions tests/Framework/MessagePartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,27 @@ public function test_normalize()
$part->normalize($headers)
);

// Mixed RFC2047 and RFC2231 encoding (#9725)
$headers = "Content-Type: application/edoc;\r\n"
. "\tname*0=\"=?UTF-8?B?ZG9rdW1lbnRzLXBhcmFrc3TEq3RzLWFyLWRyb8WhdS1lcGFyYW\";\r\n"
. "\tname*1=\"tzdA==?=\r\n"
. "\t=?UTF-8?B?YS1kcm/FoXUtcGFyYWtzdHVfdmlzc19zbGlrdGlfd\";\r\n"
. "\tname*2=\"MSBbMWray5lZG9j?=\"\r\n"
. "Content-Transfer-Encoding: base64\r\n";
$this->assertSame(
'dokuments-parakstīts-ar-drošu-eparaksta-drošu-parakstu_viss_slikti_tālūk.edoc',
$part->normalize($headers)
);

$headers = "Content-Type: text/plain;\r\n"
. " name*0=\"very very very very long very very very very l\";\r\n"
. " name*1=\"ong.txt\"\r\n"
. "Content-Transfer-Encoding: base64\r\n";
$this->assertSame(
'very very very very long very very very very long.txt',
$part->normalize($headers)
);

// TODO: Test some more corner cases
}
}

0 comments on commit 41eaff2

Please sign in to comment.