Bläddra i källkod

[DependencyInjection] fix xml validation for extension in phar archive

Martin Hason 14 år sedan
förälder
incheckning
a11619973b

+ 14 - 1
src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

@@ -281,9 +281,18 @@ class XmlFileLoader extends FileLoader
             }
         }
 
+        $tmpfiles = array();
         $imports = '';
         foreach ($schemaLocations as $namespace => $location) {
             $parts = explode('/', $location);
+            if (preg_match('/^[a-z][a-z\d\+\.\-]*:/i', $location)) { // URI scheme http://tools.ietf.org/html/rfc3986
+                $tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
+                if ($tmpfile) {
+                    file_put_contents($tmpfile, file_get_contents($location));
+                    $tmpfiles[] = $tmpfile;
+                    $parts = explode('/', str_replace('\\', '/', $tmpfile));
+                }
+            }
             $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
             $location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
 
@@ -304,7 +313,11 @@ EOF
         ;
 
         $current = libxml_use_internal_errors(true);
-        if (!$dom->schemaValidateSource($source)) {
+        $valid = $dom->schemaValidateSource($source);
+        foreach ($tmpfiles as $tmpfile) {
+            @unlink($tmpfile);
+        }
+        if (!$valid) {
             throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors()));
         }
         libxml_use_internal_errors($current);

BIN
tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar


+ 11 - 0
tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/extensions/services6.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://www.symfony-project.org/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:project="http://www.example.com/schema/projectwithxsdinphar"
+    xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
+                        http://www.example.com/schema/projectwithxsdinphar http://www.example.com/schema/projectwithxsdinphar/project-1.0.xsd">
+
+    <project:bar />
+
+</container>

+ 11 - 0
tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/extensions/services7.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://www.symfony-project.org/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:project="http://www.example.com/schema/projectwithxsdinphar"
+    xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
+                        http://www.example.com/schema/projectwithxsdinphar http://www.example.com/schema/projectwithxsdinphar/project-1.0.xsd">
+
+    <project:bar bar="foo" />
+
+</container>

+ 19 - 0
tests/Symfony/Tests/Component/DependencyInjection/Loader/XmlFileLoaderTest.php

@@ -29,6 +29,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
         require_once self::$fixturesPath.'/includes/foo.php';
         require_once self::$fixturesPath.'/includes/ProjectExtension.php';
         require_once self::$fixturesPath.'/includes/ProjectWithXsdExtension.php';
+        require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar';
     }
 
     public function testLoad()
@@ -240,6 +241,24 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    public function testExtensionInPhar()
+    {
+        // extension with an XSD in PHAR archive
+        $container = new ContainerBuilder();
+        $container->registerExtension(new \ProjectWithXsdExtensionInPhar());
+        $loader = new ProjectLoader2($container, self::$fixturesPath.'/xml');
+        $loader->load('extensions/services6.xml');
+
+        // extension with an XSD in PHAR archive (does not validate)
+        try {
+            $loader->load('extensions/services7.xml');
+            $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
+            $this->assertRegexp('/The attribute \'bar\' is not allowed/', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
+        }
+    }
+
     /**
      * @covers Symfony\Component\DependencyInjection\Loader\XmlFileLoader::supports
      */