Skip to content
This repository has been archived by the owner on Jul 12, 2019. It is now read-only.

Commit

Permalink
Backporting doctrine/instantiator#8 hotfix - uncloneable assets shoul…
Browse files Browse the repository at this point in the history
…d not be attempted to be cloned.
  • Loading branch information
Ocramius committed Oct 4, 2014
1 parent 9e6087e commit 8936cdf
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions src/Instantiator/Instantiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,29 @@ public function buildFactory($className)
};
}

/**
* Checks if a class is cloneable
*
* @internal
* @private
*
* This method is only exposed as public because of PHP 5.3 compatibility. Do not
* use this method in your own code
*
* @param ReflectionClass $class
*
* @return bool
*/
public function isSafeToClone(ReflectionClass $class)
{
if (method_exists($class, 'isCloneable') && ! $class->isCloneable()) {
return false;
}

// not cloneable if it implements `__clone`, as we want to avoid calling it
return ! $class->hasMethod('__clone');
}

/**
* @param string $className
*
Expand Down Expand Up @@ -258,16 +281,15 @@ private function getInstantiatorsMap()
private function getCloneablesMap()
{
$cachedInstantiators = $this->getInstantiatorsMap();
$that = $this;

return self::$cachedCloneables = self::$cachedCloneables
?: new CallbackLazyMap(function ($className) use ($cachedInstantiators) {
?: new CallbackLazyMap(function ($className) use ($cachedInstantiators, $that) {
/* @var $factory Closure */
$factory = $cachedInstantiators->$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 (! $that->isSafeToClone(new ReflectionClass($className))) {
return null;
}

Expand Down

0 comments on commit 8936cdf

Please sign in to comment.