Skip to content

Commit

Permalink
Validate the file size before querying the server
Browse files Browse the repository at this point in the history
  • Loading branch information
dtdesign committed May 18, 2024
1 parent 3ad1b81 commit cf03fe9
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 8 deletions.
38 changes: 35 additions & 3 deletions ts/WoltLabSuite/Core/Component/File/Upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,37 @@ function validateFileLimit(element: WoltlabCoreFileUploadElement): boolean {
return false;
}

function validateFile(element: WoltlabCoreFileUploadElement, file: File): boolean {
function validateFileSize(element: WoltlabCoreFileUploadElement, file: File): boolean {
let isImage = false;
switch (file.type) {
case "image/gif":
case "image/jpeg":
case "image/png":
case "image/webp":
isImage = true;
break;
}

// Skip the file size validation for images, they can potentially be resized.
if (isImage) {
return true;
}

const maximumSize = element.maximumSize;
if (maximumSize === -1) {
return true;
}

if (file.size <= maximumSize) {
return true;
}

innerError(element, getPhrase("wcf.upload.error.fileSizeTooLarge", { filename: file.name }));

return false;
}

function validateFileExtension(element: WoltlabCoreFileUploadElement, file: File): boolean {
const fileExtensions = (element.dataset.fileExtensions || "*").split(",");
for (const fileExtension of fileExtensions) {
if (fileExtension === "*") {
Expand All @@ -219,7 +249,9 @@ export function setup(): void {

if (!validateFileLimit(element)) {
return;
} else if (!validateFile(element, file)) {
} else if (!validateFileExtension(element, file)) {
return;
} else if (!validateFileSize(element, file)) {
return;
}

Expand All @@ -240,7 +272,7 @@ export function setup(): void {

clearPreviousErrors(element);

if (!validateFile(element, file)) {
if (!validateFileExtension(element, file)) {
promiseReject!();

return;
Expand Down
4 changes: 4 additions & 0 deletions ts/WoltLabSuite/WebComponent/woltlab-core-file-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
return parseInt(this.dataset.maximumCount || "1");
}

get maximumSize(): number {
return parseInt(this.dataset.maximumSize || "-1");
}

get disabled(): boolean {
return this.#element.disabled;
}
Expand Down
1 change: 1 addition & 0 deletions ts/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ declare global {
get disabled(): boolean;
set disabled(disabled: boolean);
get maximumCount(): number;
get maximumSize(): number;
}

interface WoltlabCoreLoadingIndicatorElement extends HTMLElement {
Expand Down

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

2 changes: 1 addition & 1 deletion wcfsetup/install/files/js/WoltLabSuite/WebComponent.min.js

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

Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ public function getMaximumCount(array $context): ?int
return 1;
}

#[\Override]
public function getMaximumSize(array $context): ?int
{
// Do not limit the maximum size of an uploaded file.
return null;
}

#[\Override]
public function getResizeConfiguration(): ResizeConfiguration
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,13 @@ public function countExistingFiles(array $context): ?int
return $attachmentHandler?->count();
}

#[\Override]
public function getMaximumSize(array $context): ?int
{
$attachmentHandler = $this->getAttachmentHandlerFromContext($context);
return $attachmentHandler?->getMaxSize();
}

private function getAttachmentHandlerFromContext(array $context): ?AttachmentHandler
{
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public function getHtmlElement(IFileProcessor $fileProcessor, array $context): s
$maximumCount = -1;
}

$maximumSize = $fileProcessor->getMaximumSize($context);
if ($maximumSize === null) {
$maximumSize = -1;
}

return \sprintf(
<<<'HTML'
<woltlab-core-file-upload
Expand All @@ -89,13 +94,15 @@ public function getHtmlElement(IFileProcessor $fileProcessor, array $context): s
data-file-extensions="%s"
data-resize-configuration="%s"
data-maximum-count="%d"
data-maximum-size="%d"
></woltlab-core-file-upload>
HTML,
StringUtil::encodeHTML($fileProcessor->getObjectTypeName()),
StringUtil::encodeHTML(JSON::encode($context)),
StringUtil::encodeHTML($allowedFileExtensions),
StringUtil::encodeHTML(JSON::encode($fileProcessor->getResizeConfiguration())),
$maximumCount,
$maximumSize,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function canDownload(File $file): bool;
* it does not track this for whatever reason.
*
* @param array<string,string> $context
* @return null|int number of existing files or `null` if this should not be enforced
* @return null|int Number of existing files or `null` if this should not be enforced
*/
public function countExistingFiles(array $context): ?int;

Expand Down Expand Up @@ -101,6 +101,14 @@ public function getFileCacheDuration(File $file): FileCacheDuration;
*/
public function getMaximumCount(array $context): ?int;

/**
* Limits the maximum size of an uploade file.
*
* @param array<string,string> $context
* @return null|int Maximum size in bytes or null to disable the limit.
*/
public function getMaximumSize(array $context): ?int;

/**
* Controls the client-side resizing of some types of images before they are
* being uploaded to the server.
Expand Down

0 comments on commit cf03fe9

Please sign in to comment.