diff --git a/src/Symfony/Component/Translation/MessageCatalogue.php b/src/Symfony/Component/Translation/MessageCatalogue.php index aa92a587fbc86..35beb3d94739a 100644 --- a/src/Symfony/Component/Translation/MessageCatalogue.php +++ b/src/Symfony/Component/Translation/MessageCatalogue.php @@ -190,6 +190,13 @@ public function addCatalogue(MessageCatalogueInterface $catalogue) public function addFallbackCatalogue(MessageCatalogueInterface $catalogue) { // detect circular references + $c = $catalogue; + while ($c = $c->getFallbackCatalogue()) { + if ($c->getLocale() === $this->getLocale()) { + throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); + } + } + $c = $this; do { if ($c->getLocale() === $catalogue->getLocale()) { diff --git a/src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php b/src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php index 7d956553d98c6..6f55b8cc5e8fb 100644 --- a/src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php +++ b/src/Symfony/Component/Translation/Tests/MessageCatalogueTest.php @@ -127,7 +127,7 @@ public function testAddFallbackCatalogue() /** * @expectedException \LogicException */ - public function testAddFallbackCatalogueWithCircularReference() + public function testAddFallbackCatalogueWithParentCircularReference() { $main = new MessageCatalogue('en_US'); $fallback = new MessageCatalogue('fr_FR'); @@ -136,6 +136,20 @@ public function testAddFallbackCatalogueWithCircularReference() $main->addFallbackCatalogue($fallback); } + /** + * @expectedException \LogicException + */ + public function testAddFallbackCatalogueWithFallbackCircularReference() + { + $fr = new MessageCatalogue('fr'); + $en = new MessageCatalogue('en'); + $es = new MessageCatalogue('es'); + + $fr->addFallbackCatalogue($en); + $es->addFallbackCatalogue($en); + $en->addFallbackCatalogue($fr); + } + /** * @expectedException \LogicException */ @@ -178,10 +192,10 @@ public function testMetadataSetGetDelete() $this->assertEquals(array(), $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 is array'); $catalogue->deleteMetadata('key2', 'messages'); - $this->assertEquals(null, $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.'); + $this->assertNull($catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.'); $catalogue->deleteMetadata('key2', 'domain'); - $this->assertEquals(null, $catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.'); + $this->assertNull($catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.'); } public function testMetadataMerge() diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index 88178f8a83f17..38c5acd7616d6 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -276,8 +276,9 @@ private function loadFallbackCatalogues($locale) $this->doLoadCatalogue($fallback); } - $current->addFallbackCatalogue($this->catalogues[$fallback]); - $current = $this->catalogues[$fallback]; + $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); + $current->addFallbackCatalogue($fallbackCatalogue); + $current = $fallbackCatalogue; } }