From f944e1f0395a36a95ba232d1d472a26249d4db08 Mon Sep 17 00:00:00 2001 From: DarkDef Date: Fri, 3 Jul 2020 19:06:49 +0300 Subject: [PATCH] Fix #18094: Support for composite file extension validation --- framework/CHANGELOG.md | 1 + framework/assets/yii.validation.js | 14 +++++++-- framework/validators/FileValidator.php | 8 +++++- .../validators/FileValidatorTest.php | 27 ++++++++++++++++++ .../validators/data/mimeType/test.tar.xz | Bin 0 -> 140 bytes 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/framework/validators/data/mimeType/test.tar.xz diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 82239fb717..a7ee89efcc 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -28,6 +28,7 @@ Yii Framework 2 Change Log - Bug #18031: HttpBasicAuth with auth callback now triggers login events same was as other authentication methods (samdark) - Bug #18134: Expression as columnName should not be quoted in likeCondition (darkdef) - Bug #18147: Fixed parameters binding for MySQL when prepare emulation is off (rskrzypczak) +- Bug #18094: Support for composite file extension validation (darkdef) 2.0.35 May 02, 2020 diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index f0118f4443..a43c4c801d 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -408,10 +408,18 @@ yii.validation = (function ($) { function validateFile(file, messages, options) { if (options.extensions && options.extensions.length > 0) { - var index = file.name.lastIndexOf('.'); - var ext = !~index ? '' : file.name.substr(index + 1, file.name.length).toLowerCase(); + var found = false; + var filename = file.name.toLowerCase(); - if (!~options.extensions.indexOf(ext)) { + for (var index=0; index < options.extensions.length; index++) { + var ext = options.extensions[index].toLowerCase(); + if (filename.substr(filename.length - options.extensions[index].length - 1) === ('.' + ext)) { + found = true; + break; + } + } + + if (!found) { messages.push(options.wrongExtension.replace(/\{file\}/g, file.name)); } } diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index 7b981cc414..f9767630e8 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -11,6 +11,7 @@ use Yii; use yii\helpers\FileHelper; use yii\helpers\Html; use yii\helpers\Json; +use yii\helpers\StringHelper; use yii\web\JsExpression; use yii\web\UploadedFile; @@ -412,7 +413,12 @@ class FileValidator extends Validator } } - if (!in_array($extension, $this->extensions, true)) { + if (!empty($this->extensions)) { + foreach ((array) $this->extensions as $ext) { + if (StringHelper::endsWith($file->name, ".$ext", false)) { + return true; + } + } return false; } diff --git a/tests/framework/validators/FileValidatorTest.php b/tests/framework/validators/FileValidatorTest.php index c3f490b08b..c787eec6b4 100644 --- a/tests/framework/validators/FileValidatorTest.php +++ b/tests/framework/validators/FileValidatorTest.php @@ -452,6 +452,32 @@ class FileValidatorTest extends TestCase $this->assertNotFalse(stripos(current($m->getErrors('attr_exe')), 'Only files with these extensions ')); } + public function testValidateAttributeDoubleType() + { + $val = new FileValidator([ + 'extensions' => 'tar.gz, tar.xz', + 'checkExtensionByMimeType' => false, + ]); + + $m = FakedValidationModel::createWithAttributes( + [ + 'attr_tar' => $this->createTestFiles([['name' => 'one.tar.gz']]), + 'attr_bar' => $this->createTestFiles([['name' => 'bad.bar.xz']]), + 'attr_badtar' => $this->createTestFiles([['name' => 'badtar.xz']]), + ] + ); + $val->validateAttribute($m, 'attr_tar'); + $this->assertFalse($m->hasErrors('attr_tar')); + + $val->validateAttribute($m, 'attr_bar'); + $this->assertTrue($m->hasErrors('attr_bar')); + $this->assertNotFalse(stripos(current($m->getErrors('attr_bar')), 'Only files with these extensions ')); + + $val->validateAttribute($m, 'attr_badtar'); + $this->assertTrue($m->hasErrors('attr_badtar')); + $this->assertNotFalse(stripos(current($m->getErrors('attr_badtar')), 'Only files with these extensions ')); + } + public function testIssue11012() { $baseName = '飛兒樂團光茫'; @@ -496,6 +522,7 @@ class FileValidatorTest extends TestCase ['test.txt', 'text/*', 'txt'], ['test.xml', '*/xml', 'xml'], ['test.odt', 'application/vnd*', 'odt'], + ['test.tar.xz', 'application/x-xz', 'tar.xz'], ]); } diff --git a/tests/framework/validators/data/mimeType/test.tar.xz b/tests/framework/validators/data/mimeType/test.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..4d2da410c2de1e3848a387c2cdf81e86c24cdfd0 GIT binary patch literal 140 zcmexsUKJ6=z`&TPbkB^5L6MOG2+Y-|Uwgp*pTRGd!AjEWoNUJem)(j}Kh)*RPD43ei{FwoR^8&I*yTHaw?uc>1~hS8S%= r%(a*1e{HiNtl$99><+;ziy0Wx8U%ps>G#?H*ctG4GXdEQjFC|Q186n- literal 0 HcmV?d00001