From b85dc27b09003914e9e19f2d1fff448ea310aa8c Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 28 Nov 2013 03:21:18 +0100 Subject: [PATCH] Hardening logic to prevent multiple unwanted initialization of public properties --- .../MethodGenerator/CallInitializer.php | 2 +- .../LazyLoadingGhostFunctionalTest.php | 27 ++++++++++++++++--- .../MethodGenerator/CallInitializerTest.php | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/ProxyManager/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializer.php b/src/ProxyManager/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializer.php index e77ce0261..92be722e7 100644 --- a/src/ProxyManager/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializer.php +++ b/src/ProxyManager/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializer.php @@ -54,7 +54,7 @@ public function __construct( $initialization = $initializationTracker->getName(); $this->setBody( - 'if ($this->' . $initialization . ') {' . "\n return;\n}\n\n" + 'if ($this->' . $initialization . ' || ! $this->' . $initializer . ') {' . "\n return;\n}\n\n" . "\$this->" . $initialization . " = true;\n\n" . "foreach (self::\$" . $publicPropertiesDefaults->getName() . " as \$key => \$default) {\n" . " \$this->\$key = \$default;\n" diff --git a/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php b/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php index c19d9a40b..30b8ceb68 100644 --- a/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php +++ b/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php @@ -207,9 +207,6 @@ public function testWillModifyByRefRetrievedPublicProperties() $this->assertSame('foo', $proxy->property0); } - /** - * Verifies that properties' default values are preserved - */ public function testKeepsInitializerWhenNotOverwitten() { $instance = new BaseClass(); @@ -224,6 +221,30 @@ public function testKeepsInitializerWhenNotOverwitten() $this->assertSame($initializer, $proxy->getProxyInitializer()); } + /** + * Verifies that public properties are not being initialized multiple times + */ + public function testKeepsInitializedPublicProperties() + { + $instance = new BaseClass(); + $proxyName = $this->generateProxy(get_class($instance)); + $initializer = function (BaseClass $proxy, $method, $parameters, & $initializer) { + $initializer = null; + $proxy->publicProperty = 'newValue'; + }; + /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */ + $proxy = new $proxyName($initializer); + + $proxy->initializeProxy(); + $this->assertSame('newValue', $proxy->publicProperty); + + $proxy->publicProperty = 'otherValue'; + + $proxy->initializeProxy(); + + $this->assertSame('otherValue', $proxy->publicProperty); + } + /** * Verifies that properties' default values are preserved */ diff --git a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php index e75ae9d01..32c0a9753 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php @@ -45,7 +45,7 @@ public function testBodyStructure() $callInitializer = new CallInitializer($initializer, $propertiesDefaults, $initializationTracker); $this->assertStringMatchesFormat( - '%Aif ($this->track) {%areturn;%a}%a' + '%Aif ($this->track || ! $this->init) {%areturn;%a}%a' . '$this->track = true;%a' . 'foreach (self::$props as $key => $default) {%a' . '$this->$key = $default;%a'