From dcfc715ecc038c125245e7aafa57cf7161dd1cd9 Mon Sep 17 00:00:00 2001 From: michalsn Date: Wed, 16 Jul 2025 08:07:58 +0200 Subject: [PATCH] fix: add filename parameters to inline Content-Disposition headers --- system/HTTP/DownloadResponse.php | 15 +++++++-------- tests/system/HTTP/DownloadResponseTest.php | 11 ++++++++++- user_guide_src/source/changelogs/v4.6.2.rst | 1 + 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/system/HTTP/DownloadResponse.php b/system/HTTP/DownloadResponse.php index a0da2e8ce4b9..f6861d549e9f 100644 --- a/system/HTTP/DownloadResponse.php +++ b/system/HTTP/DownloadResponse.php @@ -182,22 +182,21 @@ private function getDownloadFileName(): string } /** - * get Content-Disposition Header string. + * Get Content-Disposition Header string. */ - private function getContentDisposition(): string + private function getContentDisposition(bool $inline = false): string { - $downloadFilename = $this->getDownloadFileName(); - - $utf8Filename = $downloadFilename; + $downloadFilename = $utf8Filename = $this->getDownloadFileName(); + $disposition = $inline ? 'inline' : 'attachment'; if (strtoupper($this->charset) !== 'UTF-8') { $utf8Filename = mb_convert_encoding($downloadFilename, 'UTF-8', $this->charset); } - $result = sprintf('attachment; filename="%s"', $downloadFilename); + $result = sprintf('%s; filename="%s"', $disposition, addslashes($downloadFilename)); if ($utf8Filename !== '') { - $result .= '; filename*=UTF-8\'\'' . rawurlencode($utf8Filename); + $result .= sprintf('; filename*=UTF-8\'\'%s', rawurlencode($utf8Filename)); } return $result; @@ -341,7 +340,7 @@ private function sendBodyByBinary() */ public function inline() { - $this->setHeader('Content-Disposition', 'inline'); + $this->setHeader('Content-Disposition', $this->getContentDisposition(true)); return $this; } diff --git a/tests/system/HTTP/DownloadResponseTest.php b/tests/system/HTTP/DownloadResponseTest.php index 5897a1f58750..7813a08def49 100644 --- a/tests/system/HTTP/DownloadResponseTest.php +++ b/tests/system/HTTP/DownloadResponseTest.php @@ -136,7 +136,16 @@ public function testDispositionInline(): void $response = new DownloadResponse('unit-test.txt', true); $response->inline(); $response->buildHeaders(); - $this->assertSame('inline', $response->getHeaderLine('Content-Disposition')); + $this->assertSame('inline; filename="unit-test.txt"; filename*=UTF-8\'\'unit-test.txt', $response->getHeaderLine('Content-Disposition')); + } + + public function testDispositionInlineWithSetFileName(): void + { + $response = new DownloadResponse('unit-test.txt', true); + $response->setFileName('my"quoted"File.txt'); + $response->inline(); + $response->buildHeaders(); + $this->assertSame('inline; filename="my\"quoted\"File.txt"; filename*=UTF-8\'\'my%22quoted%22File.txt', $response->getHeaderLine('Content-Disposition')); } public function testNoCache(): void diff --git a/user_guide_src/source/changelogs/v4.6.2.rst b/user_guide_src/source/changelogs/v4.6.2.rst index ce2a88701a8a..dc98459ff75f 100644 --- a/user_guide_src/source/changelogs/v4.6.2.rst +++ b/user_guide_src/source/changelogs/v4.6.2.rst @@ -42,6 +42,7 @@ Bugs Fixed - **CURLRequest:** Fixed a bug where intermediate HTTP responses were not properly removed from the response chain in certain scenarios, causing incorrect status codes and headers to be returned instead of the final response. - **Database:** Fixed a bug where ``when()`` and ``whenNot()`` in ``ConditionalTrait`` incorrectly evaluated certain falsy values (such as ``[]``, ``0``, ``0.0``, and ``'0'``) as truthy, causing callbacks to be executed unexpectedly. These methods now cast the condition to a boolean using ``(bool)`` to ensure consistent behavior with PHP's native truthiness. - **Database:** Fixed encapsulation violation in ``BasePreparedQuery`` when accessing ``BaseConnection::transStatus`` protected property. +- **DownloadResponse:** Fixed a bug where ``filename`` parameters were missing from ``Content-Disposition`` headers when using inline disposition, causing browsers to use the last URL segment for filenames instead of the intended filename. - **Email:** Fixed a bug where ``Email::getHostname()`` failed to use ``$_SERVER['SERVER_ADDR']`` when ``$_SERVER['SERVER_NAME']`` was not set. - **Security:** Fixed a bug where the ``sanitize_filename()`` function from the Security helper would throw an error when used in CLI requests. - **Session:** Fixed a bug where using the ``DatabaseHandler`` with an unsupported database driver (such as ``SQLSRV``, ``OCI8``, or ``SQLite3``) did not throw an appropriate error.