From 6c5237ca36bb944cbf7ad0fe4cb78d75eee442de Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 5 Jul 2016 14:03:54 +0200 Subject: [PATCH 1/8] [varDumper] Fix missing usage of ExceptionCaster::$traceArgs --- src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 2daffea8af..513352e374 100644 --- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php @@ -234,7 +234,7 @@ class ExceptionCaster 'file' => $a[Caster::PREFIX_PROTECTED.'file'], 'line' => $a[Caster::PREFIX_PROTECTED.'line'], )); - $a[$xPrefix.'trace'] = new TraceStub($trace); + $a[$xPrefix.'trace'] = new TraceStub($trace, self::$traceArgs); } if (empty($a[$xPrefix.'previous'])) { unset($a[$xPrefix.'previous']); From d513eae29ec9349348255cdb8d15540766d8329b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Jul 2016 10:59:52 +0200 Subject: [PATCH 2/8] [ClassLoader] Fix declared classes being computed when not needed --- .../ClassLoader/ClassCollectionLoader.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php index 8046579685..b695b9272f 100644 --- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php +++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -43,12 +43,12 @@ class ClassCollectionLoader self::$loaded[$name] = true; - $declared = array_merge(get_declared_classes(), get_declared_interfaces()); - if (function_exists('get_declared_traits')) { - $declared = array_merge($declared, get_declared_traits()); - } - if ($adaptive) { + $declared = array_merge(get_declared_classes(), get_declared_interfaces()); + if (function_exists('get_declared_traits')) { + $declared = array_merge($declared, get_declared_traits()); + } + // don't include already declared classes $classes = array_diff($classes, $declared); @@ -87,11 +87,17 @@ class ClassCollectionLoader } } - if (!$reload && is_file($cache)) { + if (!$reload && file_exists($cache)) { require_once $cache; return; } + if (!$adaptive) { + $declared = array_merge(get_declared_classes(), get_declared_interfaces()); + if (function_exists('get_declared_traits')) { + $declared = array_merge($declared, get_declared_traits()); + } + } $files = array(); $content = ''; From 32cb26961451cafd7f7957c309c4068005a07654 Mon Sep 17 00:00:00 2001 From: "Konstantin.Myakshin" Date: Thu, 7 Jul 2016 18:14:45 +0300 Subject: [PATCH 3/8] [DoctrineBridge] added missing error code for constraint. --- .../Validator/Constraints/UniqueEntityValidatorTest.php | 5 +++++ .../Bridge/Doctrine/Validator/Constraints/UniqueEntity.php | 6 ++++++ .../Validator/Constraints/UniqueEntityValidator.php | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 33e484320a..95b0589fc9 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -167,6 +167,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest $this->buildViolation('myMessage') ->atPath('property.path.name') ->setInvalidValue('Foo') + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); } @@ -190,6 +191,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest $this->buildViolation('myMessage') ->atPath('property.path.bar') ->setInvalidValue('Foo') + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); } @@ -241,6 +243,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest $this->buildViolation('myMessage') ->atPath('property.path.name') ->setInvalidValue('Foo') + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); } @@ -272,6 +275,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest $this->buildViolation('myMessage') ->atPath('property.path.name2') ->setInvalidValue('Bar') + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); } @@ -404,6 +408,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest $this->buildViolation('myMessage') ->atPath('property.path.single') ->setInvalidValue($entity1) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->assertRaised(); } diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php index fc6e213bd7..315b1654e8 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php @@ -23,6 +23,8 @@ use Symfony\Component\Validator\Constraint; */ class UniqueEntity extends Constraint { + const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f'; + public $message = 'This value is already used.'; public $service = 'doctrine.orm.validator.unique'; public $em = null; @@ -31,6 +33,10 @@ class UniqueEntity extends Constraint public $errorPath = null; public $ignoreNull = true; + protected static $errorNames = array( + self::NOT_UNIQUE_ERROR => 'NOT_UNIQUE_ERROR', + ); + public function getRequiredOptions() { return array('fields'); diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index f4c8671aba..94b40f980a 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -132,11 +132,13 @@ class UniqueEntityValidator extends ConstraintValidator $this->context->buildViolation($constraint->message) ->atPath($errorPath) ->setInvalidValue($invalidValue) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->addViolation(); } else { $this->buildViolation($constraint->message) ->atPath($errorPath) ->setInvalidValue($invalidValue) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) ->addViolation(); } } From f507023e50c7e86e3fa0e6b936eb18085e1b5e58 Mon Sep 17 00:00:00 2001 From: Alexander Cheprasov Date: Wed, 6 Jul 2016 22:55:29 +0100 Subject: [PATCH 4/8] [Form] fixed bug - name in ButtonBuilder --- src/Symfony/Component/Form/ButtonBuilder.php | 5 +- .../Form/Tests/ButtonBuilderTest.php | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Form/Tests/ButtonBuilderTest.php diff --git a/src/Symfony/Component/Form/ButtonBuilder.php b/src/Symfony/Component/Form/ButtonBuilder.php index 1eaed6a826..89cad51530 100644 --- a/src/Symfony/Component/Form/ButtonBuilder.php +++ b/src/Symfony/Component/Form/ButtonBuilder.php @@ -62,11 +62,12 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface */ public function __construct($name, array $options = array()) { - if (empty($name) && 0 != $name) { + $name = (string) $name; + if ('' === $name) { throw new InvalidArgumentException('Buttons cannot have empty names.'); } - $this->name = (string) $name; + $this->name = $name; $this->options = $options; } diff --git a/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php b/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php new file mode 100644 index 0000000000..dc5d38b744 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests; + +use Symfony\Component\Form\ButtonBuilder; + +/** + * @author Alexander Cheprasov + */ +class ButtonBuilderTest extends \PHPUnit_Framework_TestCase +{ + public function getValidNames() + { + return array( + array('reset'), + array('submit'), + array('foo'), + array('0'), + array(0), + array('button[]'), + ); + } + + /** + * @dataProvider getValidNames + */ + public function testValidNames($name) + { + $this->assertInstanceOf('\Symfony\Component\Form\ButtonBuilder', new ButtonBuilder($name)); + } + + public function getInvalidNames() + { + return array( + array(''), + array(false), + array(null), + ); + } + + /** + * @dataProvider getInvalidNames + */ + public function testInvalidNames($name) + { + $this->setExpectedException( + '\Symfony\Component\Form\Exception\InvalidArgumentException', + 'Buttons cannot have empty names.' + ); + new ButtonBuilder($name); + } +} From 6344ccd7b1e1ae34dfa48b0ae979440dab86c803 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Thu, 7 Jul 2016 17:57:55 +0200 Subject: [PATCH 5/8] Make the exception message more clear. --- src/Symfony/Component/Validator/Mapping/PropertyMetadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php index 9a2a4aac14..ac71be8285 100644 --- a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php @@ -39,7 +39,7 @@ class PropertyMetadata extends MemberMetadata public function __construct($class, $name) { if (!property_exists($class, $name)) { - throw new ValidatorException(sprintf('Property %s does not exist in class %s', $name, $class)); + throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $name, $class)); } parent::__construct($class, $name, $name); From 4d68f56242a21b410c20342caa79823093228d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20V=C3=A6versted?= Date: Fri, 8 Jul 2016 11:49:25 +0200 Subject: [PATCH 6/8] [Validator] Added additional MasterCard range to the CardSchemeValidator From October 2016 MasterCard will introduce a new card range, 222100 through 272099. See: https://www.mctestcards.com/ (click the help in top right) Implements unit tests and validation for this new card range. --- .../Validator/Constraints/CardSchemeValidator.php | 2 ++ .../Tests/Constraints/CardSchemeValidatorTest.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php index 229e0d2c18..be54a0cf47 100644 --- a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php @@ -74,8 +74,10 @@ class CardSchemeValidator extends ConstraintValidator '/^6[0-9]{11,18}$/', ), // All MasterCard numbers start with the numbers 51 through 55. All have 16 digits. + // October 2016 MasterCard numbers can also start with 222100 through 272099. 'MASTERCARD' => array( '/^5[1-5][0-9]{14}$/', + '/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/', ), // All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13. 'VISA' => array( diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php index 162563e095..dbe5166451 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php @@ -102,6 +102,12 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest array('MAESTRO', '6594371785970435599'), array('MASTERCARD', '5555555555554444'), array('MASTERCARD', '5105105105105100'), + array('MASTERCARD', '2221005555554444'), + array('MASTERCARD', '2230000000000000'), + array('MASTERCARD', '2300000000000000'), + array('MASTERCARD', '2699999999999999'), + array('MASTERCARD', '2709999999999999'), + array('MASTERCARD', '2720995105105100'), array('VISA', '4111111111111111'), array('VISA', '4012888888881881'), array('VISA', '4222222222222'), @@ -129,6 +135,8 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest array('AMEX', '000000000000', CardScheme::INVALID_FORMAT_ERROR), // a lone number array('DINERS', '3056930', CardScheme::INVALID_FORMAT_ERROR), // only first part of the number array('DISCOVER', '1117', CardScheme::INVALID_FORMAT_ERROR), // only last 4 digits + array('MASTERCARD', '2721001234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet + array('MASTERCARD', '2220991234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet ); } } From 880a392d37823915cb68ca275d26c9874d217d99 Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Thu, 7 Jul 2016 09:10:40 +0200 Subject: [PATCH 7/8] [Security] Fix deprecated usage of DigestAuthenticationEntryPoint::getKey() in DigestAuthenticationListener --- .../Firewall/DigestAuthenticationListener.php | 2 +- .../DigestAuthenticationListenerTest.php | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Security/Http/Tests/Firewall/DigestAuthenticationListenerTest.php diff --git a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php index d8d71fbdd1..71bdf6ca38 100644 --- a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php @@ -78,7 +78,7 @@ class DigestAuthenticationListener implements ListenerInterface } try { - $digestAuth->validateAndDecode($this->authenticationEntryPoint->getKey(), $this->authenticationEntryPoint->getRealmName()); + $digestAuth->validateAndDecode($this->authenticationEntryPoint->getSecret(), $this->authenticationEntryPoint->getRealmName()); } catch (BadCredentialsException $e) { $this->fail($event, $request, $e); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/DigestAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/DigestAuthenticationListenerTest.php new file mode 100644 index 0000000000..80b2dc4134 --- /dev/null +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/DigestAuthenticationListenerTest.php @@ -0,0 +1,79 @@ +calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, 'GET', $uri); + + $digestData = + 'username="'.$username.'", realm="'.$realm.'", nonce="'.$nonce.'", '. + 'uri="'.$uri.'", cnonce="'.$cnonce.'", nc='.$nc.', qop="'.$qop.'", '. + 'response="'.$serverDigest.'"' + ; + + $request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_DIGEST' => $digestData)); + + $entryPoint = new DigestAuthenticationEntryPoint($realm, $secret); + + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->method('getPassword')->willReturn($password); + + $providerKey = 'TheProviderKey'; + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo(new UsernamePasswordToken($user, $password, $providerKey))) + ; + + $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); + $userProvider->method('loadUserByUsername')->willReturn($user); + + $listener = new DigestAuthenticationListener($tokenStorage, $userProvider, $providerKey, $entryPoint); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + private function calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, $method, $uri) + { + $response = md5( + md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri) + ); + + return sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"', + $username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response + ); + } +} From e90038c52e09bbb3a2c897ec7fb05467a6498e48 Mon Sep 17 00:00:00 2001 From: Malte Wunsch Date: Tue, 5 Jul 2016 10:15:40 +0200 Subject: [PATCH 8/8] [HttpKernel] fixed internal subrequests having an if-modified-since-header --- .../HttpKernel/Fragment/InlineFragmentRenderer.php | 2 ++ .../Tests/Fragment/InlineFragmentRendererTest.php | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index a6ab82ea28..a61b239c15 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -129,6 +129,8 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer } $server['REMOTE_ADDR'] = '127.0.0.1'; + unset($server['HTTP_IF_MODIFIED_SINCE']); + unset($server['HTTP_IF_NONE_MATCH']); $subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server); if ($request->headers->has('Surrogate-Capability')) { diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index 4e487a478a..d14ebb0d12 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -197,6 +197,19 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, $trustedHeaderName); } + + public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest() + { + $expectedSubRequest = Request::create('/'); + if (Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) { + $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1')); + $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1'); + } + + $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest)); + $request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*')); + $strategy->render('/', $request); + } } class Bar