Skip to content

Commit

Permalink
Merge pull request #6041 from WoltLab/upload-field-extension-validation
Browse files Browse the repository at this point in the history
Validate file extensions in `UploadFormField`
  • Loading branch information
Cyperghost authored Oct 31, 2024
2 parents 7579f8a + 22ef2dc commit 865e027
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ class UploadFormField extends AbstractFormField
*/
private $isRegistered = false;

/**
* List of allowed file extensions or `null` if the extension is not validated.
*
* @var string[]|null
* @since 6.2
*/
private ?array $allowedFileExtensions = null;

/**
* Unregisters the current field in the upload handler.
*/
Expand Down Expand Up @@ -296,6 +304,43 @@ public function validate()
}
}
}

if ($this->allowedFileExtensions !== null) {
// File extensions that contain a dot must be checked otherwise,
// the function `UploadFile::getFilenameExtension()` only returns the last part of the file extension.
//
// For example, if the file is called `blub.tar.gz`, only `gz` is returned.
// In this case, we check whether the file ends with `.tar.gz`.
$specialFileExtensions = \array_filter($this->allowedFileExtensions, function ($extension) {
return \str_contains($extension, '.');
});
$allowedFileExtensions = \array_filter($this->allowedFileExtensions, function ($extension) {
return !\str_contains($extension, '.');
});

foreach ($this->getValue() as $file) {
if (\in_array($file->getFilenameExtension(), $allowedFileExtensions)) {
continue;
}

foreach ($specialFileExtensions as $extension) {
if (\str_ends_with($file->getFilename(), ".{$extension}")) {
continue 2;
}
}

$this->addValidationError(
new FormFieldValidationError(
'acceptableFileExtensions',
'wcf.form.field.upload.error.fileExtension',
[
'allowedFileExtensions' => $this->allowedFileExtensions,
'filename' => $file->getFilename(),
]
)
);
}
}
}

/**
Expand Down Expand Up @@ -953,4 +998,26 @@ public function getAcceptableFiles()
{
return $this->acceptableFiles;
}

/**
* Returns the allowed file extensions or `null` if the extension is not validated.
*
* @since 6.2
*/
public function getAllowedFileExtensions(): ?array
{
return $this->allowedFileExtensions;
}

/**
* Specifies the allowed file extensions or `null` if the extension is not to be validated.
*
* @since 6.2
*/
public function setAllowedFileExtensions(?array $allowedFileExtensions = null): static
{
$this->allowedFileExtensions = $allowedFileExtensions;

return $this;
}
}
1 change: 1 addition & 0 deletions wcfsetup/install/lang/de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4100,6 +4100,7 @@ Dateianhänge:
<item name="wcf.form.field.upload.error.maximumImageHeight"><![CDATA[Die Datei „{$file->getFilename()}“ darf maximal {#$maximumImageHeight} Pixel hoch sein.]]></item>
<item name="wcf.form.field.upload.error.minimum"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du musst{else}Sie müssen{/if} mindestens {if $minimum > 1}{#$minimum} Dateien{else}eine Datei{/if} hochladen.]]></item>
<item name="wcf.form.field.upload.error.maximum"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du darfst{else}Sie dürfen{/if} maximal {if $maximum > 1}{#$maximum} Dateien{else}eine Datei{/if} hochladen.]]></item>
<item name="wcf.form.field.upload.error.fileExtension"><![CDATA[Die Datei „{$filename}“ hat eine ungültige Dateiendung. Erlaubt sind: {implode from=$allowedFileExtensions item=extension}{$extension}{/implode}.]]></item>
</category>
<category name="wcf.image">
<item name="wcf.image.coverPhoto"><![CDATA[Titelbild]]></item>
Expand Down
1 change: 1 addition & 0 deletions wcfsetup/install/lang/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4046,6 +4046,7 @@ Attachments:
<item name="wcf.form.field.upload.error.maximumImageHeight"><![CDATA[The file “{$file->getFilename()}” may have a maximum height of {#$maximumImageHeight} pixels.]]></item>
<item name="wcf.form.field.upload.error.minimum"><![CDATA[You must upload at least {if $minimum > 1}{#$minimum} files{else}one file{/if}.]]></item>
<item name="wcf.form.field.upload.error.maximum"><![CDATA[You can upload a maximum of {if $maximum > 1}{#$maximum} files{else}one file{/if}.]]></item>
<item name="wcf.form.field.upload.error.fileExtension"><![CDATA[The file “{$filename}” has an invalid file extension. Allowed are: {implode from=$allowedFileExtensions item=extension}{$extension}{/implode}.]]></item>
</category>
<category name="wcf.image">
<item name="wcf.image.coverPhoto"><![CDATA[Cover Photo]]></item>
Expand Down

0 comments on commit 865e027

Please sign in to comment.