Added response test and did some sanitizing

pull/663/head
n0nag0n 2 weeks ago
parent 053227b3b0
commit 4d9f0f42bd

@ -484,7 +484,7 @@ class Response
* Downloads a file. * Downloads a file.
* *
* @param string $filePath The path to the file to be downloaded. * @param string $filePath The path to the file to be downloaded.
* @param string $fileName The name the downloaded file should have. If not provided, the name of the file on disk will be used. * @param string $fileName The name the downloaded file should have. If not provided or is an empty string, the name of the file on disk will be used.
* *
* @throws Exception If the file cannot be found. * @throws Exception If the file cannot be found.
* *
@ -501,6 +501,8 @@ class Response
$mimeType = mime_content_type($filePath); $mimeType = mime_content_type($filePath);
$mimeType = $mimeType !== false ? $mimeType : 'application/octet-stream'; $mimeType = $mimeType !== false ? $mimeType : 'application/octet-stream';
// Sanitize filename to prevent header injection
$fileName = str_replace(["\r", "\n", '"'], '', $fileName);
if ($fileName === '') { if ($fileName === '') {
$fileName = basename($filePath); $fileName = basename($filePath);
} }

@ -1086,11 +1086,13 @@ class EngineTest extends TestCase
// doing this so we can overwrite some parts of the response // doing this so we can overwrite some parts of the response
$engine->getLoader()->register('response', function () { $engine->getLoader()->register('response', function () {
return new class extends Response { return new class extends Response {
public $headersSent = [];
public function setRealHeader( public function setRealHeader(
string $header_string, string $header_string,
bool $replace = true, bool $replace = true,
int $response_code = 0 int $response_code = 0
): self { ): self {
$this->headersSent[] = $header_string;
return $this; return $this;
} }
}; };
@ -1100,6 +1102,37 @@ class EngineTest extends TestCase
$streamPath = stream_get_meta_data($tmpfile)['uri']; $streamPath = stream_get_meta_data($tmpfile)['uri'];
$this->expectOutputString('I am a teapot'); $this->expectOutputString('I am a teapot');
$engine->download($streamPath); $engine->download($streamPath);
$this->assertContains('Content-Disposition: attachment; filename="'.basename($streamPath).'"', $engine->response()->headersSent);
}
public function testDownloadWithDefaultFileName(): void
{
$engine = new class extends Engine {
public function getLoader()
{
return $this->loader;
}
};
// doing this so we can overwrite some parts of the response
$engine->getLoader()->register('response', function () {
return new class extends Response {
public $headersSent = [];
public function setRealHeader(
string $header_string,
bool $replace = true,
int $response_code = 0
): self {
$this->headersSent[] = $header_string;
return $this;
}
};
});
$tmpfile = tmpfile();
fwrite($tmpfile, 'I am a teapot');
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$this->expectOutputString('I am a teapot');
$engine->download($streamPath, 'something.txt');
$this->assertContains('Content-Disposition: attachment; filename="something.txt"', $engine->response()->headersSent);
} }
public function testDownloadBadPath() { public function testDownloadBadPath() {

Loading…
Cancel
Save