Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 35ac2d1

Browse files
bug #48591 [DependencyInjection] Shared private services becomes public after a public service is accessed (alexpott)
This PR was merged into the 5.4 branch. Discussion ---------- [DependencyInjection] Shared private services becomes public after a public service is accessed | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead --> | License | MIT | Doc PR | N/a <!-- required for new features --> <!-- If a private service is an argument to at least two other services and one of those services is public. If the public service is accessed via container::get() then the private service becomes available via container::get() afterwards. Commits ------- 8437494 [DependencyInjection] Shared private services becomes public after a public service is accessed
2 parents 2b37902 + 8437494 commit 35ac2d1

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,8 @@ public function has(string $id)
546546
*/
547547
public function get(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
548548
{
549-
if ($this->isCompiled() && isset($this->removedIds[$id]) && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $invalidBehavior) {
550-
return parent::get($id);
549+
if ($this->isCompiled() && isset($this->removedIds[$id])) {
550+
return ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $invalidBehavior ? parent::get($id) : null;
551551
}
552552

553553
return $this->doGet($id, $invalidBehavior);
@@ -564,9 +564,9 @@ private function doGet(string $id, int $invalidBehavior = ContainerInterface::EX
564564
}
565565
try {
566566
if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) {
567-
return parent::get($id, $invalidBehavior);
567+
return $this->privates[$id] ?? parent::get($id, $invalidBehavior);
568568
}
569-
if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
569+
if (null !== $service = $this->privates[$id] ?? parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
570570
return $service;
571571
}
572572
} catch (ServiceCircularReferenceException $e) {
@@ -1085,8 +1085,8 @@ private function createService(Definition $definition, array &$inlineServices, b
10851085
}
10861086
}
10871087

1088-
if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) {
1089-
return $this->services[$id];
1088+
if (null !== $id && $definition->isShared() && (isset($this->services[$id]) || isset($this->privates[$id])) && ($tryProxy || !$definition->isLazy())) {
1089+
return $this->services[$id] ?? $this->privates[$id];
10901090
}
10911091

10921092
if (null !== $factory) {
@@ -1665,7 +1665,11 @@ private function shareService(Definition $definition, $service, ?string $id, arr
16651665
$inlineServices[$id ?? spl_object_hash($definition)] = $service;
16661666

16671667
if (null !== $id && $definition->isShared()) {
1668-
$this->services[$id] = $service;
1668+
if ($definition->isPrivate() && $this->isCompiled()) {
1669+
$this->privates[$id] = $service;
1670+
} else {
1671+
$this->services[$id] = $service;
1672+
}
16691673
unset($this->loading[$id]);
16701674
}
16711675
}

src/Symfony/Component/DependencyInjection/ReverseContainer.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ public function getId(object $service): ?string
6363
*/
6464
public function getService(string $id): object
6565
{
66-
if ($this->serviceContainer->has($id)) {
67-
return $this->serviceContainer->get($id);
68-
}
69-
7066
if ($this->reversibleLocator->has($id)) {
7167
return $this->reversibleLocator->get($id);
7268
}
@@ -75,7 +71,6 @@ public function getService(string $id): object
7571
throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is private and cannot be accessed by reference. You should either make it public, or tag it as "%s".', $id, $this->tagName));
7672
}
7773

78-
// will throw a ServiceNotFoundException
79-
$this->serviceContainer->get($id);
74+
return $this->serviceContainer->get($id);
8075
}
8176
}

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,10 +1105,19 @@ public function testPrivateServiceUser()
11051105
$container->addDefinitions([
11061106
'bar' => $fooDefinition,
11071107
'bar_user' => $fooUserDefinition->setPublic(true),
1108+
'bar_user2' => $fooUserDefinition->setPublic(true),
11081109
]);
11091110

11101111
$container->compile();
1112+
$this->assertNull($container->get('bar', $container::NULL_ON_INVALID_REFERENCE));
11111113
$this->assertInstanceOf(\BarClass::class, $container->get('bar_user')->bar);
1114+
1115+
// Ensure that accessing a public service with a shared private service
1116+
// does not make the private service available.
1117+
$this->assertNull($container->get('bar', $container::NULL_ON_INVALID_REFERENCE));
1118+
1119+
// Ensure the private service is still shared.
1120+
$this->assertSame($container->get('bar_user')->bar, $container->get('bar_user2')->bar);
11121121
}
11131122

11141123
public function testThrowsExceptionWhenSetServiceOnACompiledContainer()

0 commit comments

Comments
 (0)