From 9e586cc7b18c4d556dfb4cba0f76afd90e39b82c Mon Sep 17 00:00:00 2001 From: Florent Mata Date: Fri, 9 Mar 2018 21:58:48 +0100 Subject: [PATCH] [HttpFoundation] split FileException into specialized ones about upload handling --- .../Component/HttpFoundation/CHANGELOG.md | 3 + .../Exception/CannotWriteFileException.php | 21 +++++++ .../File/Exception/ExtensionFileException.php | 21 +++++++ .../File/Exception/FormSizeFileException.php | 21 +++++++ .../File/Exception/IniSizeFileException.php | 21 +++++++ .../File/Exception/NoFileException.php | 21 +++++++ .../File/Exception/NoTmpDirFileException.php | 21 +++++++ .../File/Exception/PartialFileException.php | 21 +++++++ .../HttpFoundation/File/UploadedFile.php | 24 ++++++++ .../Tests/File/UploadedFileTest.php | 56 +++++++++++++++++++ 10 files changed, 230 insertions(+) create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/CannotWriteFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/ExtensionFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/FormSizeFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/IniSizeFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/NoFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/NoTmpDirFileException.php create mode 100644 src/Symfony/Component/HttpFoundation/File/Exception/PartialFileException.php diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 15a3d2854b269..66961f16be919 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -12,6 +12,9 @@ CHANGELOG `*` and `*/*` default values (if they are present in the Accept HTTP header) when looking for items. * deprecated `Request::getSession()` when no session has been set. Use `Request::hasSession()` instead. + * added `CannotWriteFileException`, `ExtensionFileException`, `FormSizeFileException`, + `IniSizeFileException`, `NoFileException`, `NoTmpDirFileException`, `PartialFileException` to + handle failed `UploadedFile`. 4.0.0 ----- diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/CannotWriteFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/CannotWriteFileException.php new file mode 100644 index 0000000000000..c49f53a6cfe9f --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/CannotWriteFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_CANT_WRITE error occurred with UploadedFile. + * + * @author Florent Mata + */ +class CannotWriteFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/ExtensionFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/ExtensionFileException.php new file mode 100644 index 0000000000000..ed83499c004a7 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/ExtensionFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_EXTENSION error occurred with UploadedFile. + * + * @author Florent Mata + */ +class ExtensionFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/FormSizeFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/FormSizeFileException.php new file mode 100644 index 0000000000000..8741be0884c36 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/FormSizeFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_FORM_SIZE error occurred with UploadedFile. + * + * @author Florent Mata + */ +class FormSizeFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/IniSizeFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/IniSizeFileException.php new file mode 100644 index 0000000000000..c8fde6103ab27 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/IniSizeFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_INI_SIZE error occurred with UploadedFile. + * + * @author Florent Mata + */ +class IniSizeFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/NoFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/NoFileException.php new file mode 100644 index 0000000000000..4b48cc7799d2a --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/NoFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_NO_FILE error occurred with UploadedFile. + * + * @author Florent Mata + */ +class NoFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/NoTmpDirFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/NoTmpDirFileException.php new file mode 100644 index 0000000000000..bdead2d91c8a7 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/NoTmpDirFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_NO_TMP_DIR error occurred with UploadedFile. + * + * @author Florent Mata + */ +class NoTmpDirFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/PartialFileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/PartialFileException.php new file mode 100644 index 0000000000000..4641efb55a3aa --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/File/Exception/PartialFileException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\File\Exception; + +/** + * Thrown when an UPLOAD_ERR_PARTIAL error occurred with UploadedFile. + * + * @author Florent Mata + */ +class PartialFileException extends FileException +{ +} diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index 4e46aa0e15615..c4abec390dd7f 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -11,8 +11,15 @@ namespace Symfony\Component\HttpFoundation\File; +use Symfony\Component\HttpFoundation\File\Exception\CannotWriteFileException; +use Symfony\Component\HttpFoundation\File\Exception\ExtensionFileException; use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException; +use Symfony\Component\HttpFoundation\File\Exception\IniSizeFileException; +use Symfony\Component\HttpFoundation\File\Exception\NoFileException; +use Symfony\Component\HttpFoundation\File\Exception\NoTmpDirFileException; +use Symfony\Component\HttpFoundation\File\Exception\PartialFileException; use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser; /** @@ -210,6 +217,23 @@ public function move($directory, $name = null) return $target; } + switch ($this->error) { + case UPLOAD_ERR_INI_SIZE: + throw new IniSizeFileException($this->getErrorMessage()); + case UPLOAD_ERR_FORM_SIZE: + throw new FormSizeFileException($this->getErrorMessage()); + case UPLOAD_ERR_PARTIAL: + throw new PartialFileException($this->getErrorMessage()); + case UPLOAD_ERR_NO_FILE: + throw new NoFileException($this->getErrorMessage()); + case UPLOAD_ERR_CANT_WRITE: + throw new CannotWriteFileException($this->getErrorMessage()); + case UPLOAD_ERR_NO_TMP_DIR: + throw new NoTmpDirFileException($this->getErrorMessage()); + case UPLOAD_ERR_EXTENSION: + throw new ExtensionFileException($this->getErrorMessage()); + } + throw new FileException($this->getErrorMessage()); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php index b1930f02886a2..9ba22735ec5bc 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php @@ -12,6 +12,14 @@ namespace Symfony\Component\HttpFoundation\Tests\File; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\File\Exception\CannotWriteFileException; +use Symfony\Component\HttpFoundation\File\Exception\ExtensionFileException; +use Symfony\Component\HttpFoundation\File\Exception\FileException; +use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException; +use Symfony\Component\HttpFoundation\File\Exception\IniSizeFileException; +use Symfony\Component\HttpFoundation\File\Exception\NoFileException; +use Symfony\Component\HttpFoundation\File\Exception\NoTmpDirFileException; +use Symfony\Component\HttpFoundation\File\Exception\PartialFileException; use Symfony\Component\HttpFoundation\File\UploadedFile; class UploadedFileTest extends TestCase @@ -137,6 +145,54 @@ public function testMoveLocalFileIsNotAllowed() $movedFile = $file->move(__DIR__.'/Fixtures/directory'); } + public function failedUploadedFile() + { + foreach (array(UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_EXTENSION, -1) as $error) { + yield array(new UploadedFile( + __DIR__.'/Fixtures/test.gif', + 'original.gif', + 'image/gif', + $error + )); + } + } + + /** + * @dataProvider failedUploadedFile + */ + public function testMoveFailed(UploadedFile $file) + { + switch ($file->getError()) { + case UPLOAD_ERR_INI_SIZE: + $exceptionClass = IniSizeFileException::class; + break; + case UPLOAD_ERR_FORM_SIZE: + $exceptionClass = FormSizeFileException::class; + break; + case UPLOAD_ERR_PARTIAL: + $exceptionClass = PartialFileException::class; + break; + case UPLOAD_ERR_NO_FILE: + $exceptionClass = NoFileException::class; + break; + case UPLOAD_ERR_CANT_WRITE: + $exceptionClass = CannotWriteFileException::class; + break; + case UPLOAD_ERR_NO_TMP_DIR: + $exceptionClass = NoTmpDirFileException::class; + break; + case UPLOAD_ERR_EXTENSION: + $exceptionClass = ExtensionFileException::class; + break; + default: + $exceptionClass = FileException::class; + } + + $this->expectException($exceptionClass); + + $file->move(__DIR__.'/Fixtures/directory'); + } + public function testMoveLocalFileIsAllowedInTestMode() { $path = __DIR__.'/Fixtures/test.copy.gif';