From 074e1fbe357945e93c9e56c6bef0d2a10e3461c6 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Tue, 18 Jul 2017 09:22:11 -0400 Subject: [PATCH] Throw exception on circular reference detection --- lib/Twig/Environment.php | 18 +++++++++++++++++- test/Twig/Tests/EnvironmentTest.php | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index de95a7c73..35452754d 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -58,6 +58,7 @@ class Twig_Environment private $runtimeLoaders = array(); private $runtimes = array(); private $optionsHash; + private $loading = array(); /** * Constructor. @@ -472,7 +473,22 @@ class Twig_Environment $this->initRuntime(); } - return $this->loadedTemplates[$cls] = new $cls($this); + if (isset($this->loading[$cls])) { + throw new Twig_Error_Runtime(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, array($name))))); + } + + $this->loading[$cls] = $name; + + try { + $this->loadedTemplates[$cls] = new $cls($this); + unset($this->loading[$cls]); + } catch (\Exception $e) { + unset($this->loading[$cls]); + + throw $e; + } + + return $this->loadedTemplates[$cls]; } /** diff --git a/test/Twig/Tests/EnvironmentTest.php b/test/Twig/Tests/EnvironmentTest.php index 5b07c40e8..f0d42bd2a 100644 --- a/test/Twig/Tests/EnvironmentTest.php +++ b/test/Twig/Tests/EnvironmentTest.php @@ -480,6 +480,33 @@ EOF $this->assertEquals('foo', $twig->render('func_string_named_args')); } + /** + * @expectedException Twig_Error_Runtime + * @expectedExceptionMessage Circular reference detected for Twig template "base.html.twig", path: base.html.twig -> base.html.twig in "base.html.twig" at line 1 + */ + public function testFailLoadTemplateOnCircularReference() + { + $twig = new Twig_Environment(new Twig_Loader_Array(array( + 'base.html.twig' => '{% extends "base.html.twig" %}', + ))); + + $twig->loadTemplate('base.html.twig'); + } + + /** + * @expectedException Twig_Error_Runtime + * @expectedExceptionMessage Circular reference detected for Twig template "base1.html.twig", path: base1.html.twig -> base2.html.twig -> base1.html.twig in "base1.html.twig" at line 1 + */ + public function testFailLoadTemplateOnComplexCircularReference() + { + $twig = new Twig_Environment(new Twig_Loader_Array(array( + 'base1.html.twig' => '{% extends "base2.html.twig" %}', + 'base2.html.twig' => '{% extends "base1.html.twig" %}', + ))); + + $twig->loadTemplate('base1.html.twig'); + } + protected function getMockLoader($templateName, $templateContent) { // to be removed in 2.0