Bläddra i källkod

[Config] added a guard against circular references

Fabien Potencier 14 år sedan
förälder
incheckning
a98046dd44

+ 27 - 0
src/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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 <fabien@symfony.com>
+ */
+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);
+    }
+}

+ 2 - 2
src/Symfony/Component/Config/Exception/FileLoaderImportException.php

@@ -35,7 +35,7 @@ class FileLoaderImportException extends \Exception
         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 @@ class FileLoaderImportException extends \Exception
             return 'null';
         }
 
-        return str_replace("\n", '', var_export((string) $var, true));
+        return (string) $var;
     }
 }

+ 16 - 2
src/Symfony/Component/Config/Loader/FileLoader.php

@@ -13,6 +13,7 @@ namespace Symfony\Component\Config\Loader;
 
 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 @@ use Symfony\Component\Config\Exception\FileLoaderImportException;
  */
 abstract class FileLoader extends Loader
 {
+    static protected $loading = array();
+
     protected $locator;
 
     private $currentDir;
@@ -46,7 +49,7 @@ abstract class FileLoader extends Loader
     }
 
     /**
-     * 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 @@ abstract class FileLoader extends Loader
                 $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

+ 1 - 1
src/Symfony/Component/Config/Loader/Loader.php

@@ -41,7 +41,7 @@ abstract class Loader implements LoaderInterface
     }
 
     /**
-     * Adds definitions and parameters from a resource.
+     * Imports a resource.
      *
      * @param mixed  $resource A Resource
      * @param string $type     The resource type