Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix clobbering of the upload size validation #10059

Merged
merged 7 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"psr/http-message": "^1",
"sebastian/diff": "^4.0",
"silverstripe/config": "^2",
"silverstripe/assets": "^2",
"silverstripe/assets": "^2.2",
"silverstripe/vendor-plugin": "^2",
"sminnee/callbacklist": "^0.1.1",
"symfony/cache": "^6.1",
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Convert.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ public static function memstring2bytes($memString)
// Remove non-numeric characters from the size
$size = preg_replace('/[^0-9\.\-]/', '', $memString ?? '');

if (empty($size)) {
return 0;
}

if ($unit) {
// Find the position of the unit in the ordered string which is the power
// of magnitude to multiply a kilobyte by
Expand Down
5 changes: 0 additions & 5 deletions src/Forms/UploadReceiver.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ protected function constructUploadReceiver()
$this->getValidator()->setAllowedExtensions(
array_filter(File::config()->allowed_extensions ?? [])
);

// get the lower max size
$maxUpload = Convert::memstring2bytes(ini_get('upload_max_filesize'));
$maxPost = Convert::memstring2bytes(ini_get('post_max_size'));
$this->getValidator()->setAllowedMaxFileSize(min($maxUpload, $maxPost));
}

/**
Expand Down
6 changes: 5 additions & 1 deletion tests/php/Core/ConvertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,10 @@ public function memString2BytesProvider()
'mbytes' => ['512 mbytes', 512 * 1024 * 1024],
'megabytes' => ['512 megabytes', 512 * 1024 * 1024],
'giga' => ['1024g', 1024 * 1024 * 1024 * 1024],
'G' => ['1024G', 1024 * 1024 * 1024 * 1024]
'G' => ['1024G', 1024 * 1024 * 1024 * 1024],
'blank' => ['', 0],
'null' => [null, 0],
'no_numbers' => ['k', 0],
];
}

Expand All @@ -459,6 +462,7 @@ public function testBytes2MemString($bytes, $expected)
public function bytes2MemStringProvider()
{
return [
[0, '0B'],
[200, '200B'],
[2 * 1024, '2K'],
[512 * 1024 * 1024, '512M'],
Expand Down
38 changes: 38 additions & 0 deletions tests/php/Forms/FileFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SilverStripe\Forms\Tests;

use ReflectionMethod;
use SilverStripe\Core\Convert;
use SilverStripe\Assets\Upload_Validator;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Control\Controller;
Expand Down Expand Up @@ -162,4 +163,41 @@ public function testUploadMissingRequiredFile()
'A null value was passed as parameter for an uploaded file, but the validator returned true'
);
}

/**
* Test the file size validation will use the PHP max size setting if
* no config for the Upload_Validator::default_max_file_size has been defined
*/
public function testWeWillDefaultToPHPMaxUploadSizingForValidation()
{
// These 3 lines are how SilverStripe works out the default max upload size as defined in Upload_Validator
$phpMaxUpload = Convert::memstring2bytes(ini_get('upload_max_filesize'));
$maxPost = Convert::memstring2bytes(ini_get('post_max_size'));
$defaultUploadSize = min($phpMaxUpload, $maxPost);

$fileField = new FileField('DemoField');

$this->assertEquals($defaultUploadSize, $fileField->getValidator()->getAllowedMaxFileSize('jpg'));
$this->assertEquals($defaultUploadSize, $fileField->getValidator()->getAllowedMaxFileSize('png'));
}

/**
* Test the file size validation will use the default_max_file_size validation config if defined
*/
public function testWeUseConfigForSizingIfDefined()
{
$configMaxFileSizes = [
'jpg' => $jpgSize = '2m',
'*' => $defaultSize = '1m',
];

Upload_Validator::config()->set('default_max_file_size', $configMaxFileSizes);

$fileField = new FileField('DemoField');

$this->assertEquals(Convert::memstring2bytes($jpgSize), $fileField->getValidator()->getAllowedMaxFileSize('jpg'));

// PNG is not explicitly defined in config, so would fall back to *
$this->assertEquals(Convert::memstring2bytes($defaultSize), $fileField->getValidator()->getAllowedMaxFileSize('png'));
}
}