[BUGFIX] Allow empty upload fields with PSR-7 90/41190/7
authorBenjamin Mack <benni@typo3.org>
Tue, 14 Jul 2015 12:29:25 +0000 (14:29 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Tue, 14 Jul 2015 16:38:48 +0000 (18:38 +0200)
When editing a record with a regular file upload field (e.g.
a fe_users record with property image), and one does not choose
to upload a file, the PSR-7 implementation currently restricts
this. The $_FILES array is filled with an empty data set.

Thus, PSR-7 is actually canceling the whole request instead
of letting it bypass, like the DataHandler would do the same
when trying to process the uploaded files later.

The patch allows the PSR-7 implementation only to add
the files that have a filename (tmp_name) given.

Resolves: #68118
Releases: master
Change-Id: Ifdf9a59040ba6af3ca7214709f34e2e5be7f5759
Reviewed-on: http://review.typo3.org/41190
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/core/Classes/Http/ServerRequestFactory.php
typo3/sysext/core/Tests/Unit/Http/ServerRequestFactoryTest.php

index 85b5aec..1939d29 100644 (file)
@@ -110,7 +110,10 @@ class ServerRequestFactory {
                                $normalizedFileUploads[$key] = $value;
                        } elseif (is_array($value)) {
                                if (isset($value['tmp_name'])) {
-                                       $normalizedFileUploads[$key] = self::createUploadedFile($value);
+                                       $uploadedFiles = self::createUploadedFile($value);
+                                       if ($uploadedFiles) {
+                                               $normalizedFileUploads[$key] = $uploadedFiles;
+                                       }
                                } else {
                                        $normalizedFileUploads[$key] = self::normalizeUploadedFiles($value);
                                }
@@ -128,7 +131,7 @@ class ServerRequestFactory {
         * recursively resolve uploaded files.
         *
         * @param array $value $_FILES structure
-        * @return UploadedFileInterface[]|UploadedFileInterface
+        * @return UploadedFileInterface[]|UploadedFileInterface|NULL
         */
        protected static function createUploadedFile(array $value) {
                if (is_array($value['tmp_name'])) {
@@ -141,12 +144,16 @@ class ServerRequestFactory {
                                        'name'     => $value['name'][$key],
                                        'type'     => $value['type'][$key]
                                );
-                               $files[$key] = self::createUploadedFile($data);
+                               $result = self::createUploadedFile($data);
+                               if ($result) {
+                                       $files[$key] = $result;
+                               }
                        }
                        return $files;
-               } else {
+               } elseif (!empty($value['tmp_name'])) {
                        return new UploadedFile($value['tmp_name'], $value['size'], $value['error'], $value['name'], $value['type']);
                }
+               return NULL;
        }
 
 }
index 88a5213..d1f7b21 100644 (file)
@@ -81,4 +81,37 @@ class ServerRequestFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertTrue($uploadedFiles['tx_uploadexample_piexample']['newExample']['imageCollection'][0] instanceof UploadedFile);
        }
 
+       /**
+        * @test
+        */
+       public function uploadedFilesAreNotCreatedForEmptyFilesArray() {
+               $_SERVER['HTTP_HOST'] = 'localhost';
+               $_SERVER['REQUEST_URI'] = '/index.php';
+               $_FILES = array();
+
+               $uploadedFiles = ServerRequestFactory::fromGlobals()->getUploadedFiles();
+
+               $this->assertEmpty($uploadedFiles);
+       }
+
+       /**
+        * @test
+        */
+       public function uploadedFilesAreNotCreatedIfTmpNameIsEmpty() {
+               $_SERVER['HTTP_HOST'] = 'localhost';
+               $_SERVER['REQUEST_URI'] = '/index.php';
+               $_FILES = array(
+                       'tx_uploadexample_piexample' => array(
+                               'name' => '',
+                               'tmp_name' => '',
+                               'error' => 4,
+                               'size' => 0,
+                       ),
+               );
+
+               $uploadedFiles = ServerRequestFactory::fromGlobals()->getUploadedFiles();
+
+               $this->assertEmpty($uploadedFiles);
+       }
+
 }