Skip to content

Commit

Permalink
Merge pull request #8 from davedevelopment/avoid-cloning-uncloneables
Browse files Browse the repository at this point in the history
Avoid cloning uncloneables
  • Loading branch information
Ocramius committed Oct 4, 2014
2 parents 26404e0 + bf9fb07 commit 0b59c15
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/Doctrine/Instantiator/Instantiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ public function instantiate($className)
$instance = $factory();
$reflection = new ReflectionClass($instance);

// not cloneable if it implements `__clone`, as we want to avoid calling it
if (! $reflection->hasMethod('__clone')) {
if ($this->isSafeToClone($reflection)) {
self::$cachedCloneables[$className] = clone $instance;
}

Expand Down Expand Up @@ -235,4 +234,21 @@ private function isPhpVersionWithBrokenSerializationFormat()
{
return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
}

/**
* Checks if a class is cloneable
*
* @param ReflectionClass $reflection
*
* @return bool
*/
private function isSafeToClone(ReflectionClass $reflection)
{
if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) {
return false;
}

// not cloneable if it implements `__clone`, as we want to avoid calling it
return ! $reflection->hasMethod('__clone');
}
}
1 change: 1 addition & 0 deletions tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public function getInstantiableClasses()
array('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\PharExceptionAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\XMLReaderAsset'),
);

if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
Expand Down
41 changes: 41 additions & 0 deletions tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace DoctrineTest\InstantiatorTestAsset;

use BadMethodCallException;
use XMLReader;

/**
* Test asset that extends an internal PHP class
*
* @author Dave Marshall <dave@atst.io>
*/
class XMLReaderAsset extends XMLReader
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

0 comments on commit 0b59c15

Please sign in to comment.