Skip to content

Commit 24cd268

Browse files
jiripudildg
authored andcommitted
FileUpload: support directory upload (#207)
1 parent 4f156a9 commit 24cd268

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

src/Http/FileUpload.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*
1818
* @property-read string $name
1919
* @property-read string $sanitizedName
20+
* @property-read string $untrustedFullPath
2021
* @property-read string|null $contentType
2122
* @property-read int $size
2223
* @property-read string $temporaryFile
@@ -31,6 +32,7 @@ final class FileUpload
3132
public const IMAGE_MIME_TYPES = ['image/gif', 'image/png', 'image/jpeg', 'image/webp'];
3233

3334
private string $name;
35+
private string|null $fullPath;
3436
private string|false|null $type = null;
3537
private int $size;
3638
private string $tmpName;
@@ -47,6 +49,7 @@ public function __construct(?array $value)
4749
}
4850

4951
$this->name = $value['name'];
52+
$this->fullPath = $value['full_path'] ?? null;
5053
$this->size = $value['size'];
5154
$this->tmpName = $value['tmp_name'];
5255
$this->error = $value['error'];
@@ -92,6 +95,19 @@ public function getSanitizedName(): string
9295
}
9396

9497

98+
/**
99+
* Returns the original full path as submitted by the browser during directory upload. Do not trust the value
100+
* returned by this method. A client could send a malicious directory structure with the intention to corrupt
101+
* or hack your application.
102+
*
103+
* The full path is only available in PHP 8.1 and above. In previous versions, this method returns the file name.
104+
*/
105+
public function getUntrustedFullPath(): string
106+
{
107+
return $this->fullPath ?? $this->name;
108+
}
109+
110+
95111
/**
96112
* Detects the MIME content type of the uploaded file based on its signature. Requires PHP extension fileinfo.
97113
* If the upload was not successful or the detection failed, it returns null.

tests/Http/FileUpload.basic.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require __DIR__ . '/../bootstrap.php';
1515
test('', function () {
1616
$upload = new FileUpload([
1717
'name' => 'readme.txt',
18+
'full_path' => 'path/to/readme.txt',
1819
'type' => 'text/plain',
1920
'tmp_name' => __DIR__ . '/files/file.txt',
2021
'error' => 0,
@@ -24,6 +25,7 @@ test('', function () {
2425
Assert::same('readme.txt', $upload->getName());
2526
Assert::same('readme.txt', $upload->getUntrustedName());
2627
Assert::same('readme.txt', $upload->getSanitizedName());
28+
Assert::same('path/to/readme.txt', $upload->getUntrustedFullPath());
2729
Assert::same(209, $upload->getSize());
2830
Assert::same(__DIR__ . '/files/file.txt', $upload->getTemporaryFile());
2931
Assert::same(__DIR__ . '/files/file.txt', (string) $upload);
@@ -47,6 +49,7 @@ test('', function () {
4749

4850
Assert::same('../.image.png', $upload->getName());
4951
Assert::same('image.png', $upload->getSanitizedName());
52+
Assert::same('../.image.png', $upload->getUntrustedFullPath());
5053
Assert::same('image/png', $upload->getContentType());
5154
Assert::same('png', $upload->getImageFileExtension());
5255
Assert::same([108, 46], $upload->getImageSize());

0 commit comments

Comments
 (0)