8000 Merge branch '6.4' into 7.2 · symfony/symfony@0f6fd37 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0f6fd37

Browse files
committed
Merge branch '6.4' into 7.2
* 6.4: [DependencyInjection] Defer check for circular references instead of skipping them. [Validator] Synchronize IBAN formats
2 parents 385efaf + d6e0af4 commit 0f6fd37

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class CheckCircularReferencesPass implements CompilerPassInterface
2828
{
2929
private array $currentPath;
3030
private array $checkedNodes;
31+
private array $checkedLazyNodes;
3132

3233
/**
3334
* Checks the ContainerBuilder object for circular references.
@@ -57,22 +58,36 @@ private function checkOutEdges(array $edges): void
5758
$node = $edge->getDestNode();
5859
$id = $node->getId();
5960

60-
if (empty($this->checkedNodes[$id])) {
61-
// Don't check circular references for lazy edges
62-
if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) {
63-
$searchKey = array_search($id, $this->currentPath);
64-
$this->currentPath[] = $id;
61+
if (!empty($this->checkedNodes[$id])) {
62+
continue;
63+
}
64+
65+
$isLeaf = !!$node->getValue();
66+
$isConcrete = !$edge->isLazy() && !$edge->isWeak();
67+
68+
// Skip already checked lazy services if they are still lazy. Will not gain any new information.
69+
if (!empty($this->checkedLazyNodes[$id]) && (!$isLeaf || !$isConcrete)) {
70+
continue;
71+
}
6572

66-
if (false !== $searchKey) {
67-
throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey));
68-
}
73+
// Process concrete references, otherwise defer check circular references for lazy edges.
74+
if (!$isLeaf || $isConcrete) {
75+
$searchKey = array_search($id, $this->currentPath);
76+
$this->currentPath[] = $id;
6977

70-
$this->checkOutEdges($node->getOutEdges());
78+
if (false !== $searchKey) {
79+
throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey));
7180
}
7281

82+
$this->checkOutEdges($node->getOutEdges());
83+
7384
$this->checkedNodes[$id] = true;
74-
array_pop($this->currentPath);
85+
unset($this->checkedLazyNodes[$id]);
86+
} else {
87+
$this->checkedLazyNodes[$id] = true;
7588
}
89+
90+
array_pop($this->currentPath);
7691
}
7792
}
7893
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
16+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
17+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1618
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
1719
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
1820
use Symfony\Component\DependencyInjection\Compiler\Compiler;
21+
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
1922
use Symfony\Component\DependencyInjection\ContainerBuilder;
2023
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
2124
use Symfony\Component\DependencyInjection\Reference;
@@ -126,6 +129,21 @@ public function testProcessIgnoresLazyServices()
126129
$this->addToAssertionCount(1);
127130
}
128131

132+
public function testProcessDefersLazyServices()
133+
{
134+
$container = new ContainerBuilder();
135+
136+
$container->register('a')->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('tag', needsIndexes: true)));
137+
$container->register('b')->addArgument(new Reference('c'))->addTag('tag');
138+
$container->register('c')->addArgument(new Reference('b'));
139+
140+
(new ServiceLocatorTagPass())->process($container);
141+
142+
$this->expectException(ServiceCircularReferenceException::class);
143+
144+
$this->process($container);
145+
}
146+
129147
public function testProcessIgnoresIteratorArguments()
130148
{
131149
$container = new ContainerBuilder();

src/Symfony/Component/Validator/Constraints/IbanValidator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class IbanValidator extends ConstraintValidator
6969
'DK' => 'DK\d{2}\d{4}\d{9}\d{1}', // Denmark
7070
'DO' => 'DO\d{2}[\dA-Z]{4}\d{20}', // Dominican Republic
7171
'DZ' => 'DZ\d{2}\d{22}', // Algeria
72-
'EE' => 'EE\d{2}\d{2}\d{2}\d{11}\d{1}', // Estonia
72+
'EE' => 'EE\d{2}\d{2}\d{14}', // Estonia
7373
'EG' => 'EG\d{2}\d{4}\d{4}\d{17}', // Egypt
7474
'ES' => 'ES\d{2}\d{4}\d{4}\d{1}\d{1}\d{10}', // Spain
7575
'FI' => 'FI\d{2}\d{3}\d{11}', // Finland
@@ -126,7 +126,7 @@ class IbanValidator extends ConstraintValidator
126126
'MZ' => 'MZ\d{2}\d{21}', // Mozambique
127127
'NC' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France
128128
'NE' => 'NE\d{2}[A-Z]{2}\d{22}', // Niger
129-
'NI' => 'NI\d{2}[A-Z]{4}\d{24}', // Nicaragua
129+
'NI' => 'NI\d{2}[A-Z]{4}\d{20}', // Nicaragua
130130
'NL' => 'NL\d{2}[A-Z]{4}\d{10}', // Netherlands (The)
131131
'NO' => 'NO\d{2}\d{4}\d{6}\d{1}', // Norway
132132
'OM' => 'OM\d{2}\d{3}[\dA-Z]{16}', // Oman
@@ -150,7 +150,7 @@ class IbanValidator extends ConstraintValidator
150150
'SM' => 'SM\d{2}[A-Z]{1}\d{5}\d{5}[\dA-Z]{12}', // San Marino
151151
'SN' => 'SN\d{2}[A-Z]{2}\d{22}', // Senegal
152152
'SO' => 'SO\d{2}\d{4}\d{3}\d{12}', // Somalia
153-
'ST' => 'ST\d{2}\d{4}\d{4}\d{11}\d{2}', // Sao Tome and Principe
153+
'ST' => 'ST\d{2}\d{8}\d{11}\d{2}', // Sao Tome and Principe
154154
'SV' => 'SV\d{2}[A-Z]{4}\d{20}', // El Salvador
155155
'TD' => 'TD\d{2}\d{23}', // Chad
156156
'TF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France

0 commit comments

Comments
 (0)
0