From dd10034ef804d79612db0715d840d0bd6ecd7b25 Mon Sep 17 00:00:00 2001 From: Hugo Hamon Date: Fri, 19 Aug 2016 15:59:39 +0200 Subject: [PATCH 1/6] [WebProfilerBundle] replaces tabs characters by spaces. --- .../views/Collector/request.html.twig | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 136e9db9e7..6fd14ce7d3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -83,17 +83,17 @@ {% endif %} - + {% if forward_handler is defined %} -
-
- Forwarded to - - {{ forward_handler }} - ({{ collector.forward.token }}) - -
-
+
+
+ Forwarded to + + {{ forward_handler }} + ({{ collector.forward.token }}) + +
+
{% endif %} {% endset %} From 17e418caf057cb2d89786c2990209f7bdcf97410 Mon Sep 17 00:00:00 2001 From: Johann Pardanaud Date: Thu, 18 Aug 2016 22:02:09 +0200 Subject: [PATCH 2/6] Verify explicitly that the request IP is a valid IPv4 address --- src/Symfony/Component/HttpFoundation/IpUtils.php | 5 ++++- src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/IpUtils.php b/src/Symfony/Component/HttpFoundation/IpUtils.php index 82461d0159..28093be434 100644 --- a/src/Symfony/Component/HttpFoundation/IpUtils.php +++ b/src/Symfony/Component/HttpFoundation/IpUtils.php @@ -61,11 +61,14 @@ class IpUtils */ public static function checkIp4($requestIp, $ip) { + if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return false; + } + if (false !== strpos($ip, '/')) { list($address, $netmask) = explode('/', $ip, 2); if ($netmask === '0') { - // Ensure IP is valid - using ip2long below implicitly validates, but we need to do it manually here return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php b/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php index 877053f0f3..a6d28a2943 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php @@ -37,6 +37,7 @@ class IpUtilsTest extends \PHPUnit_Framework_TestCase array(true, '1.2.3.4', '0.0.0.0/0'), array(true, '1.2.3.4', '192.168.1.0/0'), array(false, '1.2.3.4', '256.256.256/0'), // invalid CIDR notation + array(false, 'an_invalid_ip', '192.168.1.0/24'), ); } From 2a7bbd124bc246d736c38c11497f10373bfeae7b Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Thu, 18 Aug 2016 19:51:07 +0000 Subject: [PATCH 3/6] [SecurityBundle] Add missing deprecation notice for form_login.intention --- .../Security/Factory/FormLoginFactory.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php index aa81aa8b92..9ac90d284e 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php @@ -52,6 +52,10 @@ class FormLoginFactory extends AbstractFactory ->ifTrue(function ($v) { return isset($v['csrf_provider']) && isset($v['csrf_token_generator']); }) ->thenInvalid("You should define a value for only one of 'csrf_provider' and 'csrf_token_generator' on a security firewall. Use 'csrf_token_generator' as this replaces 'csrf_provider'.") ->end() + ->beforeNormalization() + ->ifTrue(function ($v) { return isset($v['intention']) && isset($v['csrf_token_id']); }) + ->thenInvalid("You should define a value for only one of 'intention' and 'csrf_token_id' on a security firewall. Use 'csrf_token_id' as this replaces 'intention'.") + ->end() ->beforeNormalization() ->ifTrue(function ($v) { return isset($v['csrf_provider']); }) ->then(function ($v) { @@ -62,7 +66,18 @@ class FormLoginFactory extends AbstractFactory return $v; }) - ->end() + ->end() + ->beforeNormalization() + ->ifTrue(function ($v) { return isset($v['intention']); }) + ->then(function ($v) { + @trigger_error("Setting the 'intention' configuration key on a security firewall is deprecated since version 2.8 and will be removed in 3.0. Use the 'csrf_token_id' key instead.", E_USER_DEPRECATED); + + $v['csrf_token_id'] = $v['intention']; + unset($v['intention']); + + return $v; + }) + ->end() ->children() ->scalarNode('csrf_token_generator')->cannotBeEmpty()->end() ->end() From 99c582b4321bca0d2c4bd5ce2c44972d71524e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 17 Aug 2016 12:41:54 +0200 Subject: [PATCH 4/6] [Serializer] Fix denormalization of arrays --- .../Normalizer/AbstractObjectNormalizer.php | 14 +++++- .../Normalizer/ArrayDenormalizer.php | 19 +++++--- .../Tests/Normalizer/ObjectNormalizerTest.php | 45 +++++++++++++++++-- .../Component/Serializer/composer.json | 5 ++- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 2a8018dc0b..9ff231e7a4 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -248,8 +248,18 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer return; } - $builtinType = $type->getBuiltinType(); - $class = $type->getClassName(); + if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) { + $builtinType = Type::BUILTIN_TYPE_OBJECT; + $class = $collectionValueType->getClassName().'[]'; + + if (null !== $collectionKeyType = $type->getCollectionKeyType()) { + $context['key_type'] = $collectionKeyType; + } + } else { + $builtinType = $type->getBuiltinType(); + $class = $type->getClassName(); + } + $expectedTypes[Type::BUILTIN_TYPE_OBJECT === $builtinType && $class ? $class : $builtinType] = true; if (Type::BUILTIN_TYPE_OBJECT === $builtinType) { diff --git a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php index 921e312bd0..7d3d87c510 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Serializer\Normalizer; use Symfony\Component\Serializer\Exception\BadMethodCallException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Serializer\SerializerInterface; @@ -30,6 +31,8 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa /** * {@inheritdoc} + * + * @throws UnexpectedValueException */ public function denormalize($data, $class, $format = null, array $context = array()) { @@ -46,12 +49,16 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa $serializer = $this->serializer; $class = substr($class, 0, -2); - return array_map( - function ($data) use ($serializer, $class, $format, $context) { - return $serializer->denormalize($data, $class, $format, $context); - }, - $data - ); + $builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null; + foreach ($data as $key => $value) { + if (null !== $builtinType && !call_user_func('is_'.$builtinType, $key)) { + throw new UnexpectedValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, gettype($key))); + } + + $data[$key] = $serializer->denormalize($value, $class, $format, $context); + } + + return $data; } /** diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 8a09e516cd..ca1c4e0f59 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -12,9 +12,12 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; use Doctrine\Common\Annotations\AnnotationReader; +use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; +use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; +use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; @@ -525,13 +528,21 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase public function testDenomalizeRecursive() { - $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor()); - $serializer = new Serializer(array(new DateTimeNormalizer(), $normalizer)); + $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor())); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer)); + + $obj = $serializer->denormalize(array( + 'inner' => array('foo' => 'foo', 'bar' => 'bar'), + 'date' => '1988/01/21', + 'inners' => array(array('foo' => 1), array('foo' => 2)), + ), ObjectOuter::class); - $obj = $serializer->denormalize(array('inner' => array('foo' => 'foo', 'bar' => 'bar'), 'date' => '1988/01/21'), ObjectOuter::class); $this->assertEquals('foo', $obj->getInner()->foo); $this->assertEquals('bar', $obj->getInner()->bar); $this->assertEquals('1988-01-21', $obj->getDate()->format('Y-m-d')); + $this->assertEquals(1, $obj->getInners()[0]->foo); + $this->assertEquals(2, $obj->getInners()[1]->foo); } /** @@ -546,6 +557,19 @@ class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase $serializer->denormalize(array('date' => 'foo'), ObjectOuter::class); } + /** + * @expectedException UnexpectedValueException + * @expectedExceptionMessage The type of the key "a" must be "int" ("string" given). + */ + public function testRejectInvalidKey() + { + $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor())); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer)); + + $serializer->denormalize(array('inners' => array('a' => array('foo' => 1))), ObjectOuter::class); + } + public function testExtractAttributesRespectsFormat() { $normalizer = new FormatAndContextAwareNormalizer(); @@ -740,6 +764,11 @@ class ObjectOuter private $inner; private $date; + /** + * @var ObjectInner[] + */ + private $inners; + public function getInner() { return $this->inner; @@ -759,6 +788,16 @@ class ObjectOuter { return $this->date; } + + public function setInners(array $inners) + { + $this->inners = $inners; + } + + public function getInners() + { + return $this->inners; + } } class ObjectInner diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index 29d40aab02..01fc76bab5 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -24,9 +24,10 @@ "symfony/property-access": "~2.8|~3.0", "symfony/http-foundation": "~2.8|~3.0", "symfony/cache": "~3.1", - "symfony/property-info": "~2.8|~3.0", + "symfony/property-info": "~3.1", "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0" + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "~3.0" }, "conflict": { "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4" From fb95bdc96526fc906c93483ee917e2a1635f8280 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 16 Aug 2016 23:10:39 +0200 Subject: [PATCH 5/6] [DIC] Fix service autowiring inheritance Update Changelog --- .../ResolveDefinitionTemplatesPass.php | 4 +++ .../DefinitionDecorator.php | 10 +++++++ .../ResolveDefinitionTemplatesPassTest.php | 30 +++++++++++++++++++ .../Tests/DefinitionDecoratorTest.php | 10 +++++++ 4 files changed, 54 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php index 55f1a24513..4f8cd2b70e 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php @@ -136,6 +136,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface $def->setFile($parentDef->getFile()); $def->setPublic($parentDef->isPublic()); $def->setLazy($parentDef->isLazy()); + $def->setAutowired($parentDef->isAutowired()); // overwrite with values specified in the decorator $changes = $definition->getChanges(); @@ -169,6 +170,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface if (isset($changes['deprecated'])) { $def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%')); } + if (isset($changes['autowire'])) { + $def->setAutowired($definition->isAutowired()); + } if (isset($changes['decorated_service'])) { $decoratedService = $definition->getDecoratedService(); if (null === $decoratedService) { diff --git a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php index c03465ad42..c6ed190231 100644 --- a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php +++ b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php @@ -164,6 +164,16 @@ class DefinitionDecorator extends Definition return parent::setDeprecated($boolean, $template); } + /** + * {@inheritdoc} + */ + public function setAutowired($autowired) + { + $this->changes['autowire'] = true; + + return parent::setAutowired($autowired); + } + /** * Gets an argument to pass to the service constructor/factory method. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php index c56d199b2f..dd23e162cd 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -233,6 +233,36 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase $this->assertTrue($container->getDefinition('child1')->isLazy()); } + public function testSetAutowiredOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass'); + + $container->setDefinition('child1', new DefinitionDecorator('parent')) + ->setAutowired(true) + ; + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isAutowired()); + } + + public function testSetAutowiredOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutowired(true) + ; + + $container->setDefinition('child1', new DefinitionDecorator('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isAutowired()); + } + public function testDeepDefinitionsResolving() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php index 732eead140..4206deed28 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionDecoratorTest.php @@ -95,6 +95,16 @@ class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('lazy' => true), $def->getChanges()); } + public function testSetAutowired() + { + $def = new DefinitionDecorator('foo'); + + $this->assertFalse($def->isAutowired()); + $this->assertSame($def, $def->setAutowired(false)); + $this->assertFalse($def->isAutowired()); + $this->assertEquals(array('autowire' => true), $def->getChanges()); + } + public function testSetArgument() { $def = new DefinitionDecorator('foo'); From 107a9e50e379169096a38087c285c2071cb41656 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 22 Aug 2016 13:01:12 +0200 Subject: [PATCH 6/6] [travis] Use 7.0 until 7.1 is fixed --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 427992b88c..f7fbaa300c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ matrix: - php: 5.6 - php: 7.0 env: deps=high - - php: 7.1 + - php: 7.0 env: deps=low fast_finish: true