[BUGFIX] Fix serializable object creation with PHP 5.6 65/38765/7
authorMathias Brodala <mbrodala@pagemachine.de>
Fri, 17 Apr 2015 15:47:43 +0000 (17:47 +0200)
committerFrank Nägler <typo3@naegler.net>
Fri, 8 May 2015 21:18:02 +0000 (23:18 +0200)
This makes use of doctrine/instantiator to catch this and many
other PHP issues when instantiating objects without constructor.

Resolves: #66473
Releases: master, 6.2
Change-Id: Iaba0de638b8b555a811dad22a140d0348c168eb5
Reviewed-on: http://review.typo3.org/38765
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Frank Nägler <typo3@naegler.net>
Tested-by: Frank Nägler <typo3@naegler.net>
composer.json
typo3/sysext/extbase/Classes/Object/Container/Container.php
typo3/sysext/extbase/Tests/Unit/Object/Container/ContainerTest.php
typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/Testclasses.php

index 05da69d..e53c4c1 100644 (file)
@@ -39,7 +39,8 @@
                "swiftmailer/swiftmailer": "5.2.1",
                "symfony/console": "2.5.11",
                "helhum/class-alias-loader": "1.1.4",
-               "typo3/cms-composer-installers": "1.1.2"
+               "typo3/cms-composer-installers": "1.1.2",
+               "doctrine/instantiator": "1.0.4"
        },
        "require-dev": {
                "mikey179/vfsStream": "1.4.*@dev",
index fa12dbc..5888ef0 100644 (file)
@@ -48,6 +48,11 @@ class Container implements \TYPO3\CMS\Core\SingletonInterface {
         */
        private $classInfoFactory = NULL;
 
+       /**
+        * @var \Doctrine\Instantiator\InstantiatorInterface
+        */
+       protected $instantiator = NULL;
+
        /**
         * holds references of singletons
         *
@@ -95,6 +100,18 @@ class Container implements \TYPO3\CMS\Core\SingletonInterface {
                return $this->cache;
        }
 
+       /**
+        * Internal method to create the class instantiator, extracted to be mockable
+        *
+        * @return \Doctrine\Instantiator\InstantiatorInterface
+        */
+       protected function getInstantiator() {
+               if ($this->instantiator == NULL) {
+                       $this->instantiator = new \Doctrine\Instantiator\Instantiator();
+               }
+               return $this->instantiator;
+       }
+
        /**
         * Main method which should be used to get an instance of the wished class
         * specified by $className.
@@ -117,8 +134,7 @@ class Container implements \TYPO3\CMS\Core\SingletonInterface {
        public function getEmptyObject($className) {
                $className = $this->getImplementationClassName($className);
                $classInfo = $this->getClassInfo($className);
-               // get an object and avoid calling __construct()
-               $object = unserialize('O:' . strlen($className) . ':"' . $className . '":0:{};');
+               $object = $this->getInstantiator()->instantiate($className);
                $this->injectDependencies($object, $classInfo);
                return $object;
        }
index 7dd96a0..cfd5d02 100644 (file)
@@ -199,6 +199,14 @@ class ContainerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertInstanceOf('t3lib_object_tests_c', $object);
        }
 
+       /**
+        * @test
+        */
+       public function getEmptyObjectReturnsInstanceOfClassImplementingSerializable() {
+               $object = $this->container->getEmptyObject('t3lib_object_tests_serializable');
+               $this->assertInstanceOf('t3lib_object_tests_serializable', $object);
+       }
+
        /**
         * @test
         */
index 274cae8..7c67c44 100644 (file)
@@ -130,6 +130,14 @@ interface t3lib_object_tests_someinterface extends \TYPO3\CMS\Core\SingletonInte
 
 }
 
+/**
+ * Test class D implementing Serializable
+ */
+class t3lib_object_tests_serializable implements \Serializable {
+       public function serialize() {}
+       public function unserialize($s) {}
+}
+
 /**
  * class which implements a Interface
  */