Skip to content

Commit

Permalink
[BUGFIX] Normalize filename of uploaded files
Browse files Browse the repository at this point in the history
The filename of uploaded files might not be encoded
as normalized unicode. For instance, this happens when
using umlauts in filenames on HFS+ filesystem (macOS).

For instance the client sends an `ö`, which is sent in
NFD as `0x6fcc88`, but should be normalized as `0xc3b6`.

https://en.wikipedia.org/wiki/Unicode_equivalence#Normalization

Executed commands:
composer req symfony/polyfill-intl-normalizer:^1.27
composer req symfony/polyfill-intl-normalizer:^1.27 \
    -d typo3/sysext/core --no-update

Resolves: #101253
Releases: main, 12.4, 11.5
Change-Id: I8605481ffdc3b5d96f529850bf09a1fd75d09cd2
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/79838
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: core-ci <typo3@b13.com>
  • Loading branch information
ohader committed Jul 6, 2023
1 parent b9b8cf2 commit 5dc44cc
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 5 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -84,7 +84,7 @@
"symfony/options-resolver": "^5.4",
"symfony/polyfill-intl-icu": "^1.23.0",
"symfony/polyfill-intl-idn": "^1.23.0",
"symfony/polyfill-intl-normalizer": "^1.23.0",
"symfony/polyfill-intl-normalizer": "^1.27",
"symfony/polyfill-mbstring": "^1.23.1",
"symfony/polyfill-php80": "^1.23.1",
"symfony/polyfill-php81": "^1.23",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion typo3/sysext/core/Classes/Http/UploadedFile.php
Expand Up @@ -104,7 +104,10 @@ public function __construct($input, $size, $errorStatus, $clientFilename = null,
if ($clientFilename !== null && !is_string($clientFilename)) {
throw new \InvalidArgumentException('Invalid client filename provided for an uploaded file.', 1436717304);
}
$this->clientFilename = $clientFilename;
if (is_string($clientFilename)) {
$clientFilename = \Normalizer::normalize($clientFilename);
}
$this->clientFilename = is_string($clientFilename) ? $clientFilename : null;

if ($clientMediaType !== null && !is_string($clientMediaType)) {
throw new \InvalidArgumentException('Invalid client media type provided for an uploaded file.', 1436717305);
Expand Down
2 changes: 1 addition & 1 deletion typo3/sysext/core/Classes/Resource/ResourceStorage.php
Expand Up @@ -2149,7 +2149,7 @@ public function addUploadedFile(array $uploadedFileData, Folder $targetFolder =
$targetFolder = $this->getDefaultFolder();
}
if ($targetFileName === null) {
$targetFileName = $uploadedFileData['name'];
$targetFileName = \Normalizer::normalize($uploadedFileData['name']);
}
$targetFileName = $this->driver->sanitizeFileName($targetFileName);

Expand Down
Expand Up @@ -1086,6 +1086,10 @@ public function func_upload($cmds)
'size' => [$uploadedFileData['size']],
];
}
$uploadedFileData['name'] = array_map(
static fn (string $name) => \Normalizer::normalize($name),
$uploadedFileData['name']
);
$resultObjects = [];
$numberOfUploadedFilesForPosition = count($uploadedFileData['name']);
// Loop through all uploaded files
Expand Down
11 changes: 11 additions & 0 deletions typo3/sysext/core/Tests/Unit/Http/UploadedFileTest.php
Expand Up @@ -286,4 +286,15 @@ public function getGetStreamRaisesExceptionAfterMove(): void
$this->expectExceptionCode(1436717306);
$upload->getStream();
}

/**
* see https://en.wikipedia.org/wiki/Unicode_equivalence#Normalization, "NFD"
* @test
*/
public function nfdFileNameIsNormalized(): void
{
$clientFileName = hex2bin('6fcc88') . '.png';
$subject = new UploadedFile(fopen('php://temp', 'wb+'), 0, 0, $clientFileName);
self::assertSame(hex2bin('c3b6') . '.png', $subject->getClientFilename());
}
}
2 changes: 1 addition & 1 deletion typo3/sysext/core/composer.json
Expand Up @@ -63,7 +63,7 @@
"symfony/options-resolver": "^5.4",
"symfony/polyfill-intl-icu": "^1.23.0",
"symfony/polyfill-intl-idn": "^1.23.0",
"symfony/polyfill-intl-normalizer": "^1.23.0",
"symfony/polyfill-intl-normalizer": "^1.27",
"symfony/polyfill-mbstring": "^1.23.1",
"symfony/polyfill-php80": "^1.23.1",
"symfony/polyfill-php81": "^1.23",
Expand Down

0 comments on commit 5dc44cc

Please sign in to comment.