From 9a198c813d048789df46cccabbe76405f9709316 Mon Sep 17 00:00:00 2001
From: Benjamin Mack <benni@typo3.org>
Date: Tue, 14 Jul 2015 14:29:25 +0200
Subject: [PATCH] [BUGFIX] Allow empty upload fields with PSR-7

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>
---
 .../Classes/Http/ServerRequestFactory.php     | 15 ++++++---
 .../Unit/Http/ServerRequestFactoryTest.php    | 33 +++++++++++++++++++
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/typo3/sysext/core/Classes/Http/ServerRequestFactory.php b/typo3/sysext/core/Classes/Http/ServerRequestFactory.php
index 85b5aec569d2..1939d29a5dcf 100644
--- a/typo3/sysext/core/Classes/Http/ServerRequestFactory.php
+++ b/typo3/sysext/core/Classes/Http/ServerRequestFactory.php
@@ -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;
 	}
 
 }
diff --git a/typo3/sysext/core/Tests/Unit/Http/ServerRequestFactoryTest.php b/typo3/sysext/core/Tests/Unit/Http/ServerRequestFactoryTest.php
index 88a5213d29ba..d1f7b2147be1 100644
--- a/typo3/sysext/core/Tests/Unit/Http/ServerRequestFactoryTest.php
+++ b/typo3/sysext/core/Tests/Unit/Http/ServerRequestFactoryTest.php
@@ -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);
+	}
+
 }
-- 
GitLab