From 47f2a769c375dd9723d75ee16bdc181827b62286 Mon Sep 17 00:00:00 2001
From: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Date: Sat, 21 Apr 2018 10:06:37 +0200
Subject: [PATCH] [BUGFIX] Skip adding child elements if a nested form element
 is unknown
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Skip adding child elements within the form factory if a nested form
element is unknown.

Resolves: #84833
Releases: master, 8.7
Change-Id: I1cbb87b4c460bd45b58aa6bcca27a88c61a7e92f
Reviewed-on: https://review.typo3.org/56773
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Björn Jacob <bjoern.jacob@tritum.de>
Tested-by: Björn Jacob <bjoern.jacob@tritum.de>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-by: Mathias Brodala <mbrodala@pagemachine.de>
Tested-by: Mathias Brodala <mbrodala@pagemachine.de>
---
 .../Domain/Factory/ArrayFormFactory.php       |  6 +-
 .../Domain/Factory/ArrayFormFactoryTest.php   | 75 +++++++++++++++++++
 2 files changed, 79 insertions(+), 2 deletions(-)
 create mode 100644 typo3/sysext/form/Tests/Unit/Domain/Factory/ArrayFormFactoryTest.php

diff --git a/typo3/sysext/form/Classes/Domain/Factory/ArrayFormFactory.php b/typo3/sysext/form/Classes/Domain/Factory/ArrayFormFactory.php
index 9baf7f2f3cd4..bfbbd24d143f 100644
--- a/typo3/sysext/form/Classes/Domain/Factory/ArrayFormFactory.php
+++ b/typo3/sysext/form/Classes/Domain/Factory/ArrayFormFactory.php
@@ -112,8 +112,10 @@ class ArrayFormFactory extends AbstractFormFactory
 
         $renderable->setOptions($nestedRenderableConfiguration);
 
-        foreach ($childRenderables as $elementConfiguration) {
-            $this->addNestedRenderable($elementConfiguration, $renderable);
+        if ($renderable instanceof CompositeRenderableInterface) {
+            foreach ($childRenderables as $elementConfiguration) {
+                $this->addNestedRenderable($elementConfiguration, $renderable);
+            }
         }
 
         return $renderable;
diff --git a/typo3/sysext/form/Tests/Unit/Domain/Factory/ArrayFormFactoryTest.php b/typo3/sysext/form/Tests/Unit/Domain/Factory/ArrayFormFactoryTest.php
new file mode 100644
index 000000000000..27d87677cc35
--- /dev/null
+++ b/typo3/sysext/form/Tests/Unit/Domain/Factory/ArrayFormFactoryTest.php
@@ -0,0 +1,75 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Form\Tests\Unit\Domain\Factory;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Prophecy\Argument;
+use TYPO3\CMS\Form\Domain\Exception\IdentifierNotValidException;
+use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory;
+use TYPO3\CMS\Form\Domain\Model\FormElements\Section;
+use TYPO3\CMS\Form\Domain\Model\FormElements\UnknownFormElement;
+
+/**
+ * Test case
+ */
+class ArrayFormFactoryTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
+{
+
+    /**
+     * @test
+     */
+    public function addNestedRenderableThrowsExceptionIfIdentifierIsMissing()
+    {
+        $this->expectException(IdentifierNotValidException::class);
+        $this->expectExceptionCode(1329289436);
+
+        $section = new Section('test', 'page');
+        $arrayFormFactory = $this->getAccessibleMock(ArrayFormFactory::class, ['dummy']);
+
+        $arrayFormFactory->_call('addNestedRenderable', [], $section);
+    }
+
+    /**
+     * @test
+     */
+    public function addNestedRenderableSkipChildElementRenderingIfCompositElementIsUnknown()
+    {
+        $unknownElement = new UnknownFormElement('test-2', 'test');
+
+        $section = $this->prophesize(Section::class);
+        $section->willBeConstructedWith(['test-1', 'Section']);
+        $section->createElement(Argument::cetera())->willReturn($unknownElement);
+
+        $arrayFormFactory = $this->getAccessibleMock(ArrayFormFactory::class, ['dummy']);
+
+        $configuration = [
+            'identifier' => 'test-3',
+            'type' => 'Foo',
+            'renderables' => [
+                0 => [
+                    'identifier' => 'test-4',
+                ],
+            ],
+        ];
+
+        $typeErrorExists = false;
+        try {
+            $arrayFormFactory->_call('addNestedRenderable', $configuration, $section->reveal());
+        } catch (\TypeError $error) {
+            $typeErrorExists = true;
+        }
+        $this->assertFalse($typeErrorExists);
+    }
+}
-- 
GitLab