Skip to content

Commit 86d01b5

Browse files
Merge branch '3.3' into 3.4
* 3.3: [appveyor] set memory_limit=-1 [Router] Skip anonymous classes when loading annotated routes Fixed Request::__toString ignoring cookies Make sure we only build once and have one time the prefix when importing routes [Security] Fix fatal error on non string username
2 parents d8d85f1 + 2f8e1b8 commit 86d01b5

File tree

12 files changed

+149
-29
lines changed

12 files changed

+149
-29
lines changed

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ install:
2727
- 7z x php_memcache-3.0.8-5.5-nts-vc11-x86.zip -y >nul
2828
- cd ..
2929
- copy /Y php.ini-development php.ini-min
30+
- echo memory_limit=-1 >> php.ini-min
3031
- echo serialize_precision=14 >> php.ini-min
3132
- echo max_execution_time=1200 >> php.ini-min
3233
- echo date.timezone="America/Los_Angeles" >> php.ini-min

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,21 @@ public function __toString()
531531
return trigger_error($e, E_USER_ERROR);
532532
}
533533

534+
$cookieHeader = '';
535+
$cookies = array();
536+
537+
foreach ($this->cookies as $k => $v) {
538+
$cookies[] = $k.'='.$v;
539+
}
540+
541+
if (!empty($cookies)) {
542+
$cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
543+
}
544+
534545
return
535546
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
536-
$this->headers."\r\n".
547+
$this->headers.
548+
$cookieHeader."\r\n".
537549
$content;
538550
}
539551

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,8 +1523,18 @@ public function testToString()
15231523
$request = new Request();
15241524

15251525
$request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1526+
$request->cookies->set('Foo', 'Bar');
15261527

1527-
$this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
1528+
$asString = (string) $request;
1529+
1530+
$this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
1531+
$this->assertContains('Cookie: Foo=Bar', $asString);
1532+
1533+
$request->cookies->set('Another', 'Cookie');
1534+
1535+
$asString = (string) $request;
1536+
1537+
$this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
15281538
}
15291539

15301540
public function testIsMethod()

src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,22 @@ protected function findClass($file)
112112
}
113113

114114
if (T_CLASS === $token[0]) {
115-
// Skip usage of ::class constant
116-
$isClassConstant = false;
115+
// Skip usage of ::class constant and anonymous classes
116+
$skipClassToken = false;
117117
for ($j = $i - 1; $j > 0; --$j) {
118118
if (!isset($tokens[$j][1])) {
119119
break;
120120
}
121121

122-
if (T_DOUBLE_COLON === $tokens[$j][0]) {
123-
$isClassConstant = true;
122+
if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
123+
$skipClassToken = true;
124124
break;
125125
} elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
126126
break;
127127
}
128128
}
129129

130-
if (!$isClassConstant) {
130+
if (!$skipClassToken) {
131131
$class = true;
132132
}
133133
}

src/Symfony/Component/Routing/RouteCollectionBuilder.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ public function import($resource, $prefix = '/', $type = null)
7676
foreach ($collection->getResources() as $resource) {
7777
$builder->addResource($resource);
7878
}
79-
80-
// mount into this builder
81-
$this->mount($prefix, $builder);
8279
}
8380

81+
// mount into this builder
82+
$this->mount($prefix, $builder);
83+
8484
return $builder;
8585
}
8686

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses;
13+
14+
trait AnonymousClassInTrait
15+
{
16+
public function test()
17+
{
18+
return new class() {
19+
public function foo()
20+
{
21+
}
22+
};
23+
}
24+
}

src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ public function testLoadVariadic()
6767
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
6868
}
6969

70+
/**
71+
* @requires PHP 7.0
72+
*/
73+
public function testLoadAnonymousClass()
74+
{
75+
$this->reader->expects($this->never())->method('getClassAnnotation');
76+
$this->reader->expects($this->never())->method('getMethodAnnotations');
77+
78+
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php');
79+
}
80+
7081
public function testSupports()
7182
{
7283
$fixture = __DIR__.'/../Fixtures/annotated.php';

src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,30 @@ public function testAutomaticRouteNamesDoNotConflict()
335335
// there are 2 routes (i.e. with non-conflicting names)
336336
$this->assertCount(3, $collection->all());
337337
}
338+
339+
public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections()
340+
{
341+
$firstCollection = new RouteCollection();
342+
$firstCollection->add('a', new Route('/a'));
343+
344+
$secondCollection = new RouteCollection();
345+
$secondCollection->add('b', new Route('/b'));
346+
347+
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
348+
$loader->expects($this->any())
349+
->method('supports')
350+
->will($this->returnValue(true));
351+
$loader
352+
->expects($this->any())
353+
->method('load')
354+
->will($this->returnValue(array($firstCollection, $secondCollection)));
355+
356+
$routeCollectionBuilder = new RouteCollectionBuilder($loader);
357+
$routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob');
358+
$routes = $routeCollectionBuilder->build()->all();
359+
360+
$this->assertEquals(2, count($routes));
361+
$this->assertEquals('/other/a', $routes['a']->getPath());
362+
$this->assertEquals('/other/b', $routes['b']->getPath());
363+
}
338364
}

src/Symfony/Component/Security/Http/Firewall/ContextListener.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ class ContextListener implements ListenerInterface
4545
private $trustResolver;
4646
private $logoutOnUserChange = false;
4747

48-
private static $unserializeExceptionCode = 0x37313bc;
49-
5048
/**
5149
* @param TokenStorageInterface $tokenStorage
5250
* @param iterable|UserProviderInterface[] $userProviders
@@ -228,7 +226,7 @@ private function safelyUnserialize($serializedToken)
228226
$prevUnserializeHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
229227
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$prevErrorHandler) {
230228
if (__FILE__ === $file) {
231-
throw new \UnexpectedValueException($msg, self::$unserializeExceptionCode);
229+
throw new \UnexpectedValueException($msg, 0x37313bc);
232230
}
233231

234232
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
@@ -242,7 +240,7 @@ private function safelyUnserialize($serializedToken)
242240
restore_error_handler();
243241
ini_set('unserialize_callback_func', $prevUnserializeHandler);
244242
if ($e) {
245-
if (!$e instanceof \UnexpectedValueException || self::$unserializeExceptionCode !== $e->getCode()) {
243+
if (!$e instanceof \UnexpectedValueException || 0x37313bc !== $e->getCode()) {
246244
throw $e;
247245
}
248246
if ($this->logger) {
@@ -258,6 +256,6 @@ private function safelyUnserialize($serializedToken)
258256
*/
259257
public static function handleUnserializeCallback($class)
260258
{
261-
throw new \UnexpectedValueException('Class not found: '.$class, self::$unserializeExceptionCode);
259+
throw new \UnexpectedValueException('Class not found: '.$class, 0x37313bc);
262260
}
263261
}

src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1515
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1617
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
1718
use Symfony\Component\Security\Csrf\CsrfToken;
1819
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@@ -98,15 +99,17 @@ protected function attemptAuthentication(Request $request)
9899
}
99100
}
100101

101-
if ($this->options['post_only']) {
102-
$username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
103-
$password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
104-
} else {
105-
$username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
106-
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
102+
$requestBag = $this->options['post_only'] ? $request->request : $request;
103+
$username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']);
104+
$password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']);
105+
106+
if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) {
107+
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
107108
}
108109

109-
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
110+
$username = trim($username);
111+
112+
if (\strlen($username) > Security::MAX_USERNAME_LENGTH) {
110113
throw new BadCredentialsException('Invalid username.');
111114
}
112115

0 commit comments

Comments
 (0)