bug #14501 [ProxyBridge] Fix proxy classnames generation (xphere)

This PR was merged into the 2.3 branch.

Discussion
----------

[ProxyBridge] Fix proxy classnames generation

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | N/A
| License       | MIT
| Doc PR        | N/A

When having many lazy services based on the same class, proxy classnames collision is more prone to happen on cache regeneration.

The problem comes from [`ProxyDumper`](https://github.com/symfony/symfony/blob/2.3/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php#L112) usage of [`spl_object_hash`](http://php.net/manual/en/function.spl-object-hash.php), because object hashes may be reused for others when destroyed.

To solve this, I added more entropy with an optional salt to allow multiple passes of the `ProxyDumper`, each time with a value coming from the filepath of the cache we're building, so no collision could happen.

This applies from `symfony/2.3` to `symfony/2.7`.
Related tests are passing.

Commits
-------

afc39ee add more entropy to generated classnames
This commit is contained in:
Fabien Potencier 2015-05-05 03:48:13 +02:00
commit b77d8c5bc5
2 changed files with 12 additions and 4 deletions

View File

@ -26,6 +26,11 @@ use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
*/
class ProxyDumper implements DumperInterface
{
/**
* @var string
*/
private $salt;
/**
* @var LazyLoadingValueHolderGenerator
*/
@ -38,9 +43,12 @@ class ProxyDumper implements DumperInterface
/**
* Constructor.
*
* @param string $salt
*/
public function __construct()
public function __construct($salt = '')
{
$this->salt = $salt;
$this->proxyGenerator = new LazyLoadingValueHolderGenerator();
$this->classGenerator = new BaseGeneratorStrategy();
}
@ -109,6 +117,6 @@ EOF;
*/
private function getProxyClassName(Definition $definition)
{
return str_replace('\\', '', $definition->getClass()).'_'.spl_object_hash($definition);
return str_replace('\\', '', $definition->getClass()).'_'.spl_object_hash($definition).$this->salt;
}
}

View File

@ -243,7 +243,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
}
/**
* {@inheritDoc}
* {@inheritdoc}
*
* @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
*/
@ -683,7 +683,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$dumper = new PhpDumper($container);
if (class_exists('ProxyManager\Configuration')) {
$dumper->setProxyDumper(new ProxyDumper());
$dumper->setProxyDumper(new ProxyDumper(md5((string) $cache)));
}
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => (string) $cache));