mirror of
https://github.com/roundcube/roundcubemail.git
synced 2026-02-20 01:21:20 +01:00
fix: Sanitize filename on download (#9960)
* fix: Sanitize filename on download * fix: filename encoding in the Content-Disposition header This improves the handling of the filename* parameter in the Content-Disposition header. Now, the filename* parameter is only used when it differs from the fallback filename * tests: Add test for the filename* parameter in Content-Disposition
This commit is contained in:
@@ -256,15 +256,15 @@ abstract class rcube_output
|
||||
// @phpstan-ignore-next-line
|
||||
if (is_string($filename) && $filename !== '' && strlen($filename) <= 1024) {
|
||||
// For non-ascii characters we'll use RFC2231 syntax
|
||||
if (!preg_match('/[^a-zA-Z0-9_.:,?;@+ -]/', $filename)) {
|
||||
$disposition .= "; filename=\"{$filename}\"";
|
||||
} else {
|
||||
$fallback_filename = preg_replace('/[^a-zA-Z0-9_.(),;@+ -]/', '_', $filename);
|
||||
$disposition .= "; filename=\"{$fallback_filename}\"";
|
||||
|
||||
if ($fallback_filename != $filename) {
|
||||
$filename = rawurlencode($filename);
|
||||
$charset = $this->charset;
|
||||
if (!empty($params['charset']) && rcube_charset::is_valid($params['charset'])) {
|
||||
$charset = $params['charset'];
|
||||
}
|
||||
|
||||
$disposition .= "; filename*={$charset}''{$filename}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,15 @@ class OutputTest extends TestCase
|
||||
$this->assertContains('Content-Type: application/octet-stream', $output->headers);
|
||||
$this->assertContains('Content-Security-Policy: default-src \'none\'; img-src \'self\'', $output->headers);
|
||||
|
||||
// Test handling of filename*
|
||||
$output->reset();
|
||||
$output->download_headers('test ? test');
|
||||
|
||||
$this->assertCount(3, $output->headers);
|
||||
$this->assertContains('Content-Disposition: attachment; filename="test _ test"; filename*=' . RCUBE_CHARSET . "''" . rawurlencode('test ? test'), $output->headers);
|
||||
$this->assertContains('Content-Type: application/octet-stream', $output->headers);
|
||||
$this->assertContains('Content-Security-Policy: default-src \'none\'; img-src \'self\'', $output->headers);
|
||||
|
||||
// Invalid content type
|
||||
$output->reset();
|
||||
$params = ['type' => 'invalid'];
|
||||
|
||||
Reference in New Issue
Block a user