mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-07-15 05:41:37 +00:00
Refactored size checks for attachments and check base64 upload length
This commit is contained in:
parent
a356b94c34
commit
76a36386fc
5 changed files with 33 additions and 68 deletions
|
|
@ -74,7 +74,7 @@ class ToolsController extends AbstractController
|
|||
'detailed_error_pages' => $this->getParameter('partdb.error_pages.show_help'),
|
||||
'error_page_admin_email' => $this->getParameter('partdb.error_pages.admin_email'),
|
||||
'configured_max_file_size' => $settings->system->attachments->maxFileSize,
|
||||
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumAllowedUploadSize(),
|
||||
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumEffectiveUploadSize(),
|
||||
'saml_enabled' => $this->getParameter('partdb.saml.enabled'),
|
||||
|
||||
//PHP section
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ class AttachmentFormType extends AbstractType
|
|||
|
||||
public function finishView(FormView $view, FormInterface $form, array $options): void
|
||||
{
|
||||
$view->vars['max_upload_size'] = $this->submitHandler->getMaximumAllowedUploadSize();
|
||||
$view->vars['max_upload_size'] = $this->submitHandler->getMaximumEffectiveUploadSize();
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
|
|
|
|||
|
|
@ -218,6 +218,14 @@ class AttachmentSubmitHandler
|
|||
|
||||
//If no file was uploaded, but we have base64 encoded data, create a file from it
|
||||
if (!$file && $upload->data !== null) {
|
||||
if (strlen($upload->data) > $this->getMaximumUserConfiguredUploadSize() * 4 / 3) { //Base64 encoding increases the size of the data by 4/3, so we have to check for that
|
||||
throw new RuntimeException(
|
||||
sprintf(
|
||||
'The given base64 data is too big! Maximum size is %.1f MB!',
|
||||
$this->getMaximumUserConfiguredUploadSize() / 1000 / 1000
|
||||
));
|
||||
}
|
||||
|
||||
$file = new UploadedBase64EncodedFile(new Base64EncodedFile($upload->data), $upload->filename ?? 'base64');
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +234,15 @@ class AttachmentSubmitHandler
|
|||
|
||||
//When a file is given then upload it, otherwise check if we need to download the URL
|
||||
if ($file instanceof UploadedFile) {
|
||||
//Check the file size, to avoid uploading too big files.
|
||||
//The file is not necessarily validated as it can also come from an Base64 source
|
||||
if ($file->getSize() > $this->getMaximumUserConfiguredUploadSize()) {
|
||||
throw new RuntimeException(
|
||||
sprintf(
|
||||
'The uploaded file is too big! Maximum size is %.1f MB!',
|
||||
$this->getMaximumUserConfiguredUploadSize() / 1000 / 1000
|
||||
));
|
||||
}
|
||||
|
||||
$this->upload($attachment, $file, $secure_attachment);
|
||||
} elseif ($upload->downloadUrl && $attachment->hasExternal()) {
|
||||
|
|
@ -402,7 +419,7 @@ class AttachmentSubmitHandler
|
|||
$fileHandler = fopen($tmp_path, 'wb');
|
||||
|
||||
$bytesDownloaded = 0;
|
||||
$maxSize = $this->attachmentsSettings->getMaxFileSizeInMegabytes() * 1024 * 1024; //Convert to bytes
|
||||
$maxSize = $this->getMaximumUserConfiguredUploadSize(); //We use the maximum user configured size here, PHPs limits dont apply
|
||||
|
||||
//Write the downloaded data to file
|
||||
foreach ($this->httpClient->stream($response) as $chunk) {
|
||||
|
|
@ -418,8 +435,8 @@ class AttachmentSubmitHandler
|
|||
|
||||
throw new AttachmentDownloadException(
|
||||
sprintf(
|
||||
'The downloaded file is too big! Maximum size is %d MB!',
|
||||
$this->settings->getMaxFileSizeInMegabytes()
|
||||
'The downloaded file is too big! Maximum size is %.1f MB!',
|
||||
$maxSize / 1000 / 1000
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -527,10 +544,10 @@ class AttachmentSubmitHandler
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the maximum allowed upload size in bytes.
|
||||
* Returns the maximum effective upload size in bytes.
|
||||
* This is the minimum value of Part-DB max_file_size, and php.ini's post_max_size and upload_max_filesize.
|
||||
*/
|
||||
public function getMaximumAllowedUploadSize(): int
|
||||
public function getMaximumEffectiveUploadSize(): int
|
||||
{
|
||||
if ($this->max_upload_size_bytes) {
|
||||
return $this->max_upload_size_bytes;
|
||||
|
|
@ -545,6 +562,15 @@ class AttachmentSubmitHandler
|
|||
return $this->max_upload_size_bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum user configured upload size in bytes.
|
||||
* @return int
|
||||
*/
|
||||
public function getMaximumUserConfiguredUploadSize(): int
|
||||
{
|
||||
return $this->parseFileSizeString($this->settings->maxFileSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the given SVG file, if the attachment is an internal SVG file.
|
||||
* @param Attachment $attachment
|
||||
|
|
|
|||
|
|
@ -65,18 +65,4 @@ class AttachmentsSettings
|
|||
envVar: "bool:ATTACHMENT_SHOW_HTML_FILES", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public bool $showHTMLAttachments = false;
|
||||
|
||||
public function getMaxFileSizeInMegabytes(): int
|
||||
{
|
||||
$size = $this->maxFileSize;
|
||||
$unit = strtoupper(substr($size, -1));
|
||||
$value = (int) rtrim($size, 'KMG');
|
||||
|
||||
return match ($unit) {
|
||||
'K' => (int) ceil($value / 1024),
|
||||
'M' => $value,
|
||||
'G' => $value * 1024,
|
||||
default => $value, // No unit specified, assume megabytes
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Settings\SystemSettings;
|
||||
|
||||
use App\Settings\SystemSettings\AttachmentsSettings;
|
||||
use App\Tests\SettingsTestHelper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AttachmentsSettingsTest extends TestCase
|
||||
{
|
||||
|
||||
public function testGetMaxFileSizeInMegabytes(): void
|
||||
{
|
||||
$settings = SettingsTestHelper::createSettingsDummy(AttachmentsSettings::class);
|
||||
|
||||
$settings->maxFileSize = '100M';
|
||||
$this->assertEquals(100, $settings->getMaxFileSizeInMegabytes());
|
||||
|
||||
$settings->maxFileSize = '1G';
|
||||
$this->assertEquals(1024, $settings->getMaxFileSizeInMegabytes());
|
||||
|
||||
//We round up to the next megabyte if the file size is smaller than 1 MB
|
||||
$settings->maxFileSize = '500K';
|
||||
$this->assertEquals(1, $settings->getMaxFileSizeInMegabytes());
|
||||
|
||||
$settings->maxFileSize = '13.5M';
|
||||
$this->assertEquals(13, $settings->getMaxFileSizeInMegabytes());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue