[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)
@@ -49,6 +49,11 @@ class Container implements \TYPO3\CMS\Core\SingletonInterface {
        private $classInfoFactory = NULL;
 
        /**
+        * @var \Doctrine\Instantiator\InstantiatorInterface
+        */
+       protected $instantiator = NULL;
+
+       /**
         * holds references of singletons
         *
         * @var array
@@ -96,6 +101,18 @@ class Container implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * 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)
@@ -202,6 +202,14 @@ class ContainerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @test
         */
+       public function getEmptyObjectReturnsInstanceOfClassImplementingSerializable() {
+               $object = $this->container->getEmptyObject('t3lib_object_tests_serializable');
+               $this->assertInstanceOf('t3lib_object_tests_serializable', $object);
+       }
+
+       /**
+        * @test
+        */
        public function test_canGetChildClass() {
                $object = $this->container->getInstance('t3lib_object_tests_b_child');
                $this->assertInstanceOf('t3lib_object_tests_b_child', $object);
index 274cae8..7c67c44 100644 (file)
@@ -131,6 +131,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
  */
 class t3lib_object_tests_someimplementation implements \t3lib_object_tests_someinterface {