From d02ca2512b198bbac84593d4a6611819e5e9ce88 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Wed, 22 Feb 2012 22:42:42 +0100 Subject: [PATCH 1/9] [MonologBundle] Fixed a bug when adding a processor on a service handler --- .../Compiler/AddProcessorsPass.php | 2 +- .../Compiler/AddProcessorsPassTest.php | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php index 83b2b13fec..d91bfb2d80 100644 --- a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/AddProcessorsPass.php @@ -35,7 +35,7 @@ class AddProcessorsPass implements CompilerPassInterface } if (!empty($tag['handler'])) { - $definition = $container->getDefinition(sprintf('monolog.handler.%s', $tag['handler'])); + $definition = $container->findDefinition(sprintf('monolog.handler.%s', $tag['handler'])); } elseif (!empty($tag['channel'])) { if ('app' === $tag['channel']) { $definition = $container->getDefinition('monolog.logger'); diff --git a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php new file mode 100644 index 0000000000..99374b1023 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass; +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + +class AddProcessorsPassTest extends TestCase +{ + public function testHandlerProcessors() + { + $container = $this->getContainer(); + + $service = $container->getDefinition('monolog.handler.test'); + $calls = $service->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals(array('pushProcessor', array(new Reference('test'))), $calls[0]); + + $service = $container->getDefinition('handler_test'); + $calls = $service->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals(array('pushProcessor', array(new Reference('test2'))), $calls[0]); + } + + protected function getContainer() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config')); + $loader->load('monolog.xml'); + + $definition = $container->getDefinition('monolog.logger_prototype'); + $container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->setDefinition('handler_test', new Definition('%monolog.handler.null.class%', array (100, false))); + $container->setAlias('monolog.handler.test2', 'handler_test'); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test'))); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test2'))); + + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.processor', array ('handler' => 'test')); + $container->setDefinition('test', $service); + + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.processor', array ('handler' => 'test2')); + $container->setDefinition('test2', $service); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->addCompilerPass(new AddProcessorsPass()); + $container->compile(); + + return $container; + } +} From 6e75fd16c85d563d3e98a5541cc78645639ce4c8 Mon Sep 17 00:00:00 2001 From: John Bohn Date: Mon, 23 Jan 2012 10:54:35 -0600 Subject: [PATCH 2/9] Resolves issue with spl_autoload_register creating new copies of the container and passing that into the closure. --- src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php b/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php index 2ef73a3839..7bd97e9421 100644 --- a/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php +++ b/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php @@ -42,9 +42,9 @@ class DoctrineBundle extends Bundle if ($this->container->hasParameter('doctrine.orm.proxy_namespace')) { $namespace = $this->container->getParameter('doctrine.orm.proxy_namespace'); $dir = $this->container->getParameter('doctrine.orm.proxy_dir'); - $container = $this->container; + $container =& $this->container; - spl_autoload_register(function($class) use ($namespace, $dir, $container) { + spl_autoload_register(function($class) use ($namespace, $dir, &$container) { if (0 === strpos($class, $namespace)) { $className = substr($class, strlen($namespace) +1); $file = $dir.DIRECTORY_SEPARATOR.$className.'.php'; From 24a3cd35406f2c8e9b57146857d01f1223af82ad Mon Sep 17 00:00:00 2001 From: Pavel Campr Date: Fri, 24 Feb 2012 01:10:57 +0100 Subject: [PATCH 3/9] Finder - allow sorting when searching in multiple directories --- src/Symfony/Component/Finder/Finder.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 826de17937..ee03832267 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -502,7 +502,8 @@ class Finder implements \IteratorAggregate } if ($this->sort) { - $iterator = new Iterator\SortableIterator($iterator, $this->sort); + $iterator_aggregate = new Iterator\SortableIterator($iterator, $this->sort); + $iterator = $iterator_aggregate->getIterator(); } return $iterator; From 15910a015b6355a21598d4b1dbe3d9f921253e7b Mon Sep 17 00:00:00 2001 From: Pavel Campr Date: Fri, 24 Feb 2012 09:04:00 +0100 Subject: [PATCH 4/9] fixed coding standards --- src/Symfony/Component/Finder/Finder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index ee03832267..d2feef080c 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -502,8 +502,8 @@ class Finder implements \IteratorAggregate } if ($this->sort) { - $iterator_aggregate = new Iterator\SortableIterator($iterator, $this->sort); - $iterator = $iterator_aggregate->getIterator(); + $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort); + $iterator = $iteratorAggregate->getIterator(); } return $iterator; From 66d0d3dd4b6cb0749541f55e3aca015b2dc658fc Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Tue, 7 Feb 2012 19:06:41 +0100 Subject: [PATCH 5/9] [FrameworkBundle] Fix a bug in the RedirectableUrlMatcher --- .../Routing/RedirectableUrlMatcher.php | 5 +- .../Routing/RedirectableUrlMatcherTest.php | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php b/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php index c08badac42..8a3607d397 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php @@ -11,13 +11,12 @@ namespace Symfony\Bundle\FrameworkBundle\Routing; -use Symfony\Component\Routing\Matcher\UrlMatcher; -use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; +use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher; /** * @author Fabien Potencier */ -class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +class RedirectableUrlMatcher extends BaseMatcher { /** * Redirects the user to another URL. diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php new file mode 100644 index 0000000000..55c0125ed7 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php @@ -0,0 +1,61 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Routing; + +use Symfony\Bundle\FrameworkBundle\Routing\Router; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher; +use Symfony\Component\Routing\RequestContext; + +class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase +{ + public function testRedirectWhenNoSlash() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo/')); + + $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); + + $this->assertEquals(array( + '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', + 'path' => '/foo/', + 'permanent' => true, + 'scheme' => null, + 'httpPort' => $context->getHttpPort(), + 'httpsPort' => $context->getHttpsPort(), + '_route' => null, + ), + $matcher->match('/foo') + ); + } + + public function testSchemeRedirect() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo', array(), array('_scheme' => 'https'))); + + $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); + + $this->assertEquals(array( + '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', + 'path' => '/foo', + 'permanent' => true, + 'scheme' => 'https', + 'httpPort' => $context->getHttpPort(), + 'httpsPort' => $context->getHttpsPort(), + '_route' => 'foo', + ), + $matcher->match('/foo') + ); + } +} \ No newline at end of file From 3e64d36cbdc34acaa82e0e6318112cd2eacb6fec Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 24 Feb 2012 13:26:13 +0100 Subject: [PATCH 6/9] [Serializer] Fix XML decoding attack vector through external entities --- .../Serializer/Encoder/XmlEncoder.php | 11 +++++++++++ .../Serializer/Encoder/XmlEncoderTest.php | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 4ffe330d6f..54fae35917 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -54,7 +54,18 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec */ public function decode($data, $format) { + $internalErrors = libxml_use_internal_errors(true); + $disableEntities = libxml_disable_entity_loader(true); + libxml_clear_errors(); + $xml = simplexml_load_string($data); + libxml_use_internal_errors($internalErrors); + libxml_disable_entity_loader($disableEntities); + + if ($error = libxml_get_last_error()) { + throw new UnexpectedValueException($error->message); + } + if (!$xml->count()) { if (!$xml->attributes()) { return (string) $xml; diff --git a/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php b/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php index 22bff31a62..e4aef6563a 100644 --- a/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php +++ b/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php @@ -9,6 +9,7 @@ use Symfony\Tests\Component\Serializer\Fixtures\Dummy; use Symfony\Tests\Component\Serializer\Fixtures\ScalarDummy; use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Serializer; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Normalizer\CustomNormalizer; /* @@ -232,6 +233,23 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, $this->encoder->decode($source, 'xml')); } + /** + * @expectedException Symfony\Component\Serializer\Exception\UnexpectedValueException + */ + public function testPreventsComplexExternalEntities() + { + $oldCwd = getcwd(); + chdir(__DIR__); + + try { + $decoded = $this->encoder->decode(']>&test;', 'xml'); + chdir($oldCwd); + } catch (UnexpectedValueException $e) { + chdir($oldCwd); + throw $e; + } + } + protected function getXmlSource() { return ''."\n". From 71b62276d31d0a3d90eac9d2008db90d5f918959 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 24 Feb 2012 22:55:48 +0100 Subject: [PATCH 7/9] fixed a test --- .../Tests/Routing/RedirectableUrlMatcherTest.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php index 55c0125ed7..2b669bbd15 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php @@ -47,15 +47,9 @@ class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase $matcher = new RedirectableUrlMatcher($coll, $context = new RequestContext()); $this->assertEquals(array( - '_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', - 'path' => '/foo', - 'permanent' => true, - 'scheme' => 'https', - 'httpPort' => $context->getHttpPort(), - 'httpsPort' => $context->getHttpsPort(), - '_route' => 'foo', + '_route' => 'foo', ), $matcher->match('/foo') ); } -} \ No newline at end of file +} From 51ba6ffc6dd0a1f72977667a25fa956528cc4f1f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 24 Feb 2012 22:59:05 +0100 Subject: [PATCH 8/9] updated CHANGELOG for 2.0.11 --- CHANGELOG-2.0.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG-2.0.md b/CHANGELOG-2.0.md index 25e5a85e1b..e6642d20ca 100644 --- a/CHANGELOG-2.0.md +++ b/CHANGELOG-2.0.md @@ -7,6 +7,17 @@ in 2.0 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.0.0...v2.0.1 +* 2.0.11 (2012-02-24) + + * 3e64d36: [Serializer] Fix XML decoding attack vector through external entities + * 66d0d3d: [FrameworkBundle] Fix a bug in the RedirectableUrlMatcher + * 24a3cd3: Finder - allow sorting when searching in multiple directories + * 6e75fd1: Resolves issue with spl_autoload_register creating new copies of the container and passing that into the closure. + * d02ca25: [MonologBundle] Fixed a bug when adding a processor on a service handler + * 2434552: [Translation] Fixed fallback location if location is longer than three characters (possibly by mistake). + * ec7fb0b: [Routing] added a proper exception when a route pattern references the same variable more than once (closes #3344) + * beb4fc0: [WIP][Locale] StubIntlDateFormatter::parse was throwing exception instead of returning Boolean false like intl implementation + * 2.0.10 (2012-02-06) * 8e13095: Fixed the unescaping of parameters to handle arrays From 2d4fb8ad502a80af475c7232b5497571ed32a641 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 24 Feb 2012 22:59:39 +0100 Subject: [PATCH 9/9] updated VERSION for 2.0.11 --- src/Symfony/Component/HttpKernel/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index f0a2f08334..f7745906eb 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -57,7 +57,7 @@ abstract class Kernel implements KernelInterface protected $startTime; protected $classes; - const VERSION = '2.0.11-DEV'; + const VERSION = '2.0.11'; /** * Constructor.