diff --git a/src/Illuminate/Filesystem/FilesystemAdapter.php b/src/Illuminate/Filesystem/FilesystemAdapter.php index 6734ae18f6b4..9198c757da86 100644 --- a/src/Illuminate/Filesystem/FilesystemAdapter.php +++ b/src/Illuminate/Filesystem/FilesystemAdapter.php @@ -141,7 +141,7 @@ public function response($path, $name = null, array $headers = [], $disposition $filename = $name ?? basename($path); $disposition = $response->headers->makeDisposition( - $disposition, $filename, Str::ascii($filename) + $disposition, $filename, $this->fallbackName($filename) ); $response->headers->replace($headers + [ @@ -172,6 +172,17 @@ public function download($path, $name = null, array $headers = []) return $this->response($path, $name, $headers, 'attachment'); } + /** + * Convert the string to ASCII characters that are equivalent to the given name. + * + * @param string $name + * @return string + */ + protected function fallbackName($name) + { + return str_replace('%', '', Str::ascii($name)); + } + /** * Write the contents of a file. * diff --git a/tests/Filesystem/FilesystemAdapterTest.php b/tests/Filesystem/FilesystemAdapterTest.php index 7c111e9c29c7..3be440b353a3 100644 --- a/tests/Filesystem/FilesystemAdapterTest.php +++ b/tests/Filesystem/FilesystemAdapterTest.php @@ -70,6 +70,15 @@ public function testDownloadNonAsciiEmptyFilename() $this->assertEquals('attachment; filename=pizdyuk.txt; filename*=utf-8\'\'%D0%BF%D0%B8%D0%B7%D0%B4%D1%8E%D0%BA.txt', $response->headers->get('content-disposition')); } + public function testDownloadPercentInFilename() + { + $this->filesystem->write('Hello%World.txt', 'Hello World'); + $files = new FilesystemAdapter($this->filesystem); + $response = $files->download('Hello%World.txt', 'Hello%World.txt'); + $this->assertInstanceOf(StreamedResponse::class, $response); + $this->assertEquals('attachment; filename=HelloWorld.txt; filename*=utf-8\'\'Hello%25World.txt', $response->headers->get('content-disposition')); + } + public function testExists() { $this->filesystem->write('file.txt', 'Hello World');