From a98046dd4456042e54b73164eea4fe6e25290238 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 5 Jun 2011 10:52:57 +0200 Subject: [PATCH] [Config] added a guard against circular references --- ...LoaderImportCircularReferenceException.php | 27 +++++++++++++++++++ .../Exception/FileLoaderImportException.php | 4 +-- .../Component/Config/Loader/FileLoader.php | 18 +++++++++++-- .../Component/Config/Loader/Loader.php | 2 +- 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php diff --git a/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php new file mode 100644 index 000000000000..f56d903c1469 --- /dev/null +++ b/src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Exception; + +/** + * Exception class for when a circular reference is detected when importing resources. + * + * @author Fabien Potencier + */ +class FileLoaderImportCircularReferenceException extends FileLoaderImportException +{ + public function __construct(array $resources, $code = null, $previous = null) + { + $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]); + + call_user_func('Exception::__construct', $message, $code, $previous); + } +} diff --git a/src/Symfony/Component/Config/Exception/FileLoaderImportException.php b/src/Symfony/Component/Config/Exception/FileLoaderImportException.php index cfab0f532620..c5488626407d 100644 --- a/src/Symfony/Component/Config/Exception/FileLoaderImportException.php +++ b/src/Symfony/Component/Config/Exception/FileLoaderImportException.php @@ -35,7 +35,7 @@ public function __construct($resource, $sourceResource, $code = null, $previous parent::__construct($message, $code, $previous); } - private function varToString($var) + protected function varToString($var) { if (is_object($var)) { return sprintf('[object](%s)', get_class($var)); @@ -58,6 +58,6 @@ private function varToString($var) return 'null'; } - return str_replace("\n", '', var_export((string) $var, true)); + return (string) $var; } } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Loader/FileLoader.php b/src/Symfony/Component/Config/Loader/FileLoader.php index b03ddde64047..eead9523b12a 100644 --- a/src/Symfony/Component/Config/Loader/FileLoader.php +++ b/src/Symfony/Component/Config/Loader/FileLoader.php @@ -13,6 +13,7 @@ use Symfony\Component\Config\FileLocatorInterface; use Symfony\Component\Config\Exception\FileLoaderImportException; +use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException; /** * FileLoader is the abstract class used by all built-in loaders that are file based. @@ -21,6 +22,8 @@ */ abstract class FileLoader extends Loader { + static protected $loading = array(); + protected $locator; private $currentDir; @@ -46,7 +49,7 @@ public function getLocator() } /** - * Adds definitions and parameters from a resource. + * Imports a resource. * * @param mixed $resource A Resource * @param string $type The resource type @@ -64,7 +67,18 @@ public function import($resource, $type = null, $ignoreErrors = false, $sourceRe $resource = $this->locator->locate($resource, $this->currentDir); } - return $loader->load($resource); + if (isset(self::$loading[$resource])) { + throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading)); + } + self::$loading[$resource] = true; + + $ret = $loader->load($resource); + + unset(self::$loading[$resource]); + + return $ret; + } catch (FileLoaderImportCircularReferenceException $e) { + throw $e; } catch (\Exception $e) { if (!$ignoreErrors) { // prevent embedded imports from nesting multiple exceptions diff --git a/src/Symfony/Component/Config/Loader/Loader.php b/src/Symfony/Component/Config/Loader/Loader.php index f02110c28e64..999a3b040390 100644 --- a/src/Symfony/Component/Config/Loader/Loader.php +++ b/src/Symfony/Component/Config/Loader/Loader.php @@ -41,7 +41,7 @@ public function setResolver(LoaderResolver $resolver) } /** - * Adds definitions and parameters from a resource. + * Imports a resource. * * @param mixed $resource A Resource * @param string $type The resource type