Skip to content

Commit 6b5d35f

Browse files
Merge branch '3.2' into 3.3
* 3.2: [DI] Handle root namespace in service definitions Use rawurlencode() to transform the Cookie into a string [Security] Fix authentication.failure event not dispatched on AccountStatusException
2 parents e659ec1 + e51c1a5 commit 6b5d35f

File tree

8 files changed

+88
-14
lines changed

8 files changed

+88
-14
lines changed

src/Symfony/Component/BrowserKit/Cookie.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function __construct($name, $value, $expires = null, $path = null, $domai
6262
$this->rawValue = $value;
6363
} else {
6464
$this->value = $value;
65-
$this->rawValue = urlencode($value);
65+
$this->rawValue = rawurlencode($value);
6666
}
6767
$this->name = $name;
6868
$this->path = empty($path) ? '/' : $path;

src/Symfony/Component/BrowserKit/Tests/CookieTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@
1616

1717
class CookieTest extends TestCase
1818
{
19+
public function testToString()
20+
{
21+
$cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
22+
$this->assertEquals('foo=bar; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
23+
24+
$cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
25+
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
26+
27+
$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
28+
$this->assertEquals('foo=; expires=Thu, 01 Jan 1970 00:00:01 GMT; domain=.myfoodomain.com; path=/admin/; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
29+
30+
$cookie = new Cookie('foo', 'bar', 0, '/', '');
31+
$this->assertEquals('foo=bar; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; httponly', (string) $cookie);
32+
}
33+
1934
/**
2035
* @dataProvider getTestsForToFromString
2136
*/

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -397,15 +397,9 @@ private function addServiceReturn($id, $isSimpleInstance)
397397
*/
398398
private function addServiceInstance($id, Definition $definition, $isSimpleInstance)
399399
{
400-
$class = $definition->getClass();
401-
402-
if ('\\' === substr($class, 0, 1)) {
403-
$class = substr($class, 1);
404-
}
405-
406-
$class = $this->dumpValue($class);
400+
$class = $this->dumpValue($definition->getClass());
407401

408-
if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
402+
if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
409403
throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id));
410404
}
411405

@@ -1564,11 +1558,13 @@ private function dumpLiteralClass($class)
15641558
if (false !== strpos($class, '$')) {
15651559
return sprintf('${($_ = %s) && false ?: "_"}', $class);
15661560
}
1567-
if (0 !== strpos($class, "'") || !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
1561+
if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
15681562
throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s)', $class ?: 'n/a'));
15691563
}
15701564

1571-
return '\\'.substr(str_replace('\\\\', '\\', $class), 1, -1);
1565+
$class = substr(str_replace('\\\\', '\\', $class), 1, -1);
1566+
1567+
return 0 === strpos($class, '\\') ? $class : '\\'.$class;
15721568
}
15731569

15741570
/**

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,4 +584,17 @@ public function testPrivateWithIgnoreOnInvalidReference()
584584
$container = new \Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference();
585585
$this->assertInstanceOf('BazClass', $container->get('bar')->getBaz());
586586
}
587+
588+
public function testDumpHandlesLiteralClassWithRootNamespace()
589+
{
590+
$container = new ContainerBuilder();
591+
$container->register('foo', '\\stdClass');
592+
593+
$dumper = new PhpDumper($container);
594+
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace')));
595+
596+
$container = new \Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace();
597+
598+
$this->assertInstanceOf('stdClass', $container->get('foo'));
599+
}
587600
}

src/Symfony/Component/HttpFoundation/Cookie.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public function __toString()
145145
if ('' === (string) $this->getValue()) {
146146
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001';
147147
} else {
148-
$str .= $this->isRaw() ? $this->getValue() : urlencode($this->getValue());
148+
$str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
149149

150150
if (0 !== $this->getExpiresTime()) {
151151
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; max-age='.$this->getMaxAge();

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ public function testToString()
164164
$cookie = new Cookie('foo', 'bar', $expire = strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
165165
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
166166

167+
$cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
168+
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
169+
167170
$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
168171
$this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; max-age='.($expire - time()).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
169172

src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ public function authenticate(TokenInterface $token)
8181
break;
8282
}
8383
} catch (AccountStatusException $e) {
84-
$e->setToken($token);
84+
$lastException = $e;
8585

86-
throw $e;
86+
break;
8787
} catch (AuthenticationException $e) {
8888
$lastException = $e;
8989
}

src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
16+
use Symfony\Component\Security\Core\AuthenticationEvents;
17+
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
18+
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
1619
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
1720
use Symfony\Component\Security\Core\Exception\AuthenticationException;
1821
use Symfony\Component\Security\Core\Exception\AccountStatusException;
@@ -125,6 +128,50 @@ public function testEraseCredentialFlag()
125128
$this->assertEquals('bar', $token->getCredentials());
126129
}
127130

131+
public function testAuthenticateDispatchesAuthenticationFailureEvent()
132+
{
133+
$token = new UsernamePasswordToken('foo', 'bar', 'key');
134+
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();
135+
$provider->expects($this->once())->method('supports')->willReturn(true);
136+
$provider->expects($this->once())->method('authenticate')->willThrowException($exception = new AuthenticationException());
137+
138+
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
139+
$dispatcher
140+
->expects($this->once())
141+
->method('dispatch')
142+
->with(AuthenticationEvents::AUTHENTICATION_FAILURE, $this->equalTo(new AuthenticationFailureEvent($token, $exception)));
143+
144+
$manager = new AuthenticationProviderManager(array($provider));
145+
$manager->setEventDispatcher($dispatcher);
146+
147+
try {
148+
$manager->authenticate($token);
149+
$this->fail('->authenticate() should rethrow exceptions');
150+
} catch (AuthenticationException $e) {
151+
$this->assertSame($token, $exception->getToken());
152+
}
153+
}
154+
155+
public function testAuthenticateDispatchesAuthenticationSuccessEvent()
156+
{
157+
$token = new UsernamePasswordToken('foo', 'bar', 'key');
158+
159+
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();
160+
$provider->expects($this->once())->method('supports')->willReturn(true);
161+
$provider->expects($this->once())->method('authenticate')->willReturn($token);
162+
163+
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
164+
$dispatcher
165+
->expects($this->once())
166+
->method('dispatch')
167+
->with(AuthenticationEvents::AUTHENTICATION_SUCCESS, $this->equalTo(new AuthenticationEvent($token)));
168+
169+
$manager = new AuthenticationProviderManager(array($provider));
170+
$manager->setEventDispatcher($dispatcher);
171+
172+
$this->assertSame($token, $manager->authenticate($token));
173+
}
174+
128175
protected function getAuthenticationProvider($supports, $token = null, $exception = null)
129176
{
130177
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();

0 commit comments

Comments
 (0)