Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a8cc059

Browse files
Merge branch '5.0'
* 5.0: [Yaml] Throw on unquoted exclamation mark Use supportsClass where possible
2 parents b5d52a3 + 6c1265c commit a8cc059

File tree

6 files changed

+158
-13
lines changed

6 files changed

+158
-13
lines changed

src/Symfony/Component/Security/Core/Tests/User/ChainUserProviderTest.php

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,62 @@ public function testRefreshUser()
7070
$provider1 = $this->getProvider();
7171
$provider1
7272
->expects($this->once())
73-
->method('refreshUser')
74-
->willThrowException(new UnsupportedUserException('unsupported'))
73+
->method('supportsClass')
74+
->willReturn(false)
7575
;
7676

7777
$provider2 = $this->getProvider();
78+
$provider2
79+
->expects($this->once())
80+
->method('supportsClass')
81+
->willReturn(true)
82+
;
83+
7884
$provider2
85+
->expects($this->once())
86+
->method('refreshUser')
87+
->willThrowException(new UnsupportedUserException('unsupported'))
88+
;
89+
90+
$provider3 = $this->getProvider();
91+
$provider3
92+
->expects($this->once())
93+
->method('supportsClass')
94+
->willReturn(true)
95+
;
96+
97+
$provider3
7998
->expects($this->once())
8099
->method('refreshUser')
81100
->willReturn($account = $this->getAccount())
82101
;
83102

84-
$provider = new ChainUserProvider([$provider1, $provider2]);
103+
$provider = new ChainUserProvider([$provider1, $provider2, $provider3]);
85104
$this->assertSame($account, $provider->refreshUser($this->getAccount()));
86105
}
87106

88107
public function testRefreshUserAgain()
89108
{
90109
$provider1 = $this->getProvider();
110+
$provider1
111+
->expects($this->once())
112+
->method('supportsClass')
113+
->willReturn(true)
114+
;
115+
91116
$provider1
92117
->expects($this->once())
93118
->method('refreshUser')
94119
->willThrowException(new UsernameNotFoundException('not found'))
95120
;
96121

97122
$provider2 = $this->getProvider();
123+
$provider2
124+
->expects($this->once())
125+
->method('supportsClass')
126+
->willReturn(true)
127+
;
128+
98129
$provider2
99130
->expects($this->once())
100131
->method('refreshUser')
@@ -109,13 +140,25 @@ public function testRefreshUserThrowsUnsupportedUserException()
109140
{
110141
$this->expectException('Symfony\Component\Security\Core\Exception\UnsupportedUserException');
111142
$provider1 = $this->getProvider();
143+
$provider1
144+
->expects($this->once())
145+
->method('supportsClass')
146+
->willReturn(true)
147+
;
148+
112149
$provider1
113150
->expects($this->once())
114151
->method('refreshUser')
115152
->willThrowException(new UnsupportedUserException('unsupported'))
116153
;
117154

118155
$provider2 = $this->getProvider();
156+
$provider2
157+
->expects($this->once())
158+
->method('supportsClass')
159+
->willReturn(true)
160+
;
161+
119162
$provider2
120163
->expects($this->once())
121164
->method('refreshUser')
@@ -173,13 +216,25 @@ public function testSupportsClassWhenNotSupported()
173216
public function testAcceptsTraversable()
174217
{
175218
$provider1 = $this->getProvider();
219+
$provider1
220+
->expects($this->once())
221+
->method('supportsClass')
222+
->willReturn(true)
223+
;
224+
176225
$provider1
177226
->expects($this->once())
178227
->method('refreshUser')
179228
->willThrowException(new UnsupportedUserException('unsupported'))
180229
;
181230

182231
$provider2 = $this->getProvider();
232+
$provider2
233+
->expects($this->once())
234+
->method('supportsClass')
235+
->willReturn(true)
236+
;
237+
183238
$provider2
184239
->expects($this->once())
185240
->method('refreshUser')

src/Symfony/Component/Security/Core/User/ChainUserProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ public function refreshUser(UserInterface $user)
7373

7474
foreach ($this->providers as $provider) {
7575
try {
76+
if (!$provider->supportsClass(\get_class($user))) {
77+
continue;
78+
}
79+
7680
return $provider->refreshUser($user);
7781
} catch (UnsupportedUserException $e) {
7882
// try next one

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,17 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface
197197

198198
$userNotFoundByProvider = false;
199199
$userDeauthenticated = false;
200+
$userClass = \get_class($user);
200201

201202
foreach ($this->userProviders as $provider) {
202203
if (!$provider instanceof UserProviderInterface) {
203204
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "%s".', \get_class($provider), UserProviderInterface::class));
204205
}
205206

207+
if (!$provider->supportsClass($userClass)) {
208+
continue;
209+
}
210+
206211
try {
207212
$refreshedUser = $provider->refreshUser($user);
208213
$newToken = clone $token;
@@ -259,7 +264,7 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface
259264
return null;
260265
}
261266

262-
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', \get_class($user)));
267+
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', $userClass));
263268
}
264269

265270
private function safelyUnserialize(string $serializedToken)

src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ public function testHandleRemovesTokenIfNoPreviousSessionWasFound()
253253
public function testIfTokenIsDeauthenticated()
254254
{
255255
$refreshedUser = new User('foobar', 'baz');
256-
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]);
256+
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]);
257257

258258
$this->assertNull($tokenStorage->getToken());
259259
}
@@ -275,44 +275,44 @@ public function testRememberMeGetsCanceledIfTokenIsDeauthenticated()
275275
$rememberMeServices = $this->createMock(RememberMeServicesInterface::class);
276276
$rememberMeServices->expects($this->once())->method('loginFail');
277277

278-
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], null, $rememberMeServices);
278+
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, $rememberMeServices);
279279

280280
$this->assertNull($tokenStorage->getToken());
281281
}
282282

283283
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
284284
{
285285
$refreshedUser = new User('foobar', 'baz');
286-
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser);
286+
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
287287

288288
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
289289
}
290290

291291
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
292292
{
293293
$refreshedUser = new User('foobar', 'baz');
294-
$tokenStorage = $this->handleEventWithPreviousSession([new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser);
294+
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
295295

296296
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
297297
}
298298

299299
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
300300
{
301-
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider()]);
301+
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider()]);
302302

303303
$this->assertNull($tokenStorage->getToken());
304304
}
305305

306306
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
307307
{
308308
$this->expectException('RuntimeException');
309-
$this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new NotSupportingUserProvider()]);
309+
$this->handleEventWithPreviousSession([new NotSupportingUserProvider(false), new NotSupportingUserProvider(true)]);
310310
}
311311

312312
public function testAcceptsProvidersAsTraversable()
313313
{
314314
$refreshedUser = new User('foobar', 'baz');
315-
$tokenStorage = $this->handleEventWithPreviousSession(new \ArrayObject([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
315+
$tokenStorage = $this->handleEventWithPreviousSession(new \ArrayObject([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
316316

317317
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
318318
}
@@ -338,7 +338,7 @@ public function testDeauthenticatedEvent()
338338
$this->assertNotEquals($event->getRefreshedToken()->getUser(), $user);
339339
});
340340

341-
$listener = new ContextListener($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], 'context_key', null, $eventDispatcher);
341+
$listener = new ContextListener($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], 'context_key', null, $eventDispatcher);
342342
$listener(new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
343343

344344
$this->assertNull($tokenStorage->getToken());
@@ -422,14 +422,26 @@ private function handleEventWithPreviousSession($userProviders, UserInterface $u
422422

423423
class NotSupportingUserProvider implements UserProviderInterface
424424
{
425+
/** @var bool */
426+
private $throwsUnsupportedException;
427+
428+
public function __construct($throwsUnsupportedException)
429+
{
430+
$this->throwsUnsupportedException = $throwsUnsupportedException;
431+
}
432+
425433
public function loadUserByUsername($username): UserInterface
426434
{
427435
throw new UsernameNotFoundException();
428436
}
429437

430438
public function refreshUser(UserInterface $user): UserInterface
431439
{
432-
throw new UnsupportedUserException();
440+
if ($this->throwsUnsupportedException) {
441+
throw new UnsupportedUserException();
442+
}
443+
444+
return $user;
433445
}
434446

435447
public function supportsClass($class): bool

src/Symfony/Component/Yaml/Inline.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ private static function parseTag(string $value, int &$i, int $flags): ?string
679679
$nextOffset = $i + $tagLength + 1;
680680
$nextOffset += strspn($value, ' ', $nextOffset);
681681

682+
if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) {
683+
throw new ParseException(sprintf('Using the unquoted scalar value "!" is not supported. You must quote it.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
684+
}
685+
682686
// Is followed by a scalar and is a built-in tag
683687
if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
684688
// Manage in {@link self::evaluateScalar()}

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,4 +737,69 @@ public function getTestsForOctalNumbers()
737737
'negative octal number' => [-28, '-034'],
738738
];
739739
}
740+
741+
/**
742+
* @dataProvider unquotedExclamationMarkThrowsProvider
743+
*/
744+
public function testUnquotedExclamationMarkThrows(string $value)
745+
{
746+
$this->expectException(ParseException::class);
747+
$this->expectExceptionMessageRegExp('/^Using the unquoted scalar value "!" is not supported\. You must quote it at line 1 \(near "/');
748+
749+
Inline::parse($value);
750+
}
751+
752+
public function unquotedExclamationMarkThrowsProvider()
753+
{
754+
return [
755+
['!'],
756+
['! '],
757+
['! '],
758+
[' ! '],
759+
['[!]'],
760+
['[! ]'],
761+
['[! ]'],
762+
['[!, "foo"]'],
763+
['["foo", !, "ccc"]'],
764+
['{foo: !}'],
765+
['{foo: !}'],
766+
['{foo: !, bar: "ccc"}'],
767+
['{bar: "ccc", foo: ! }'],
768+
['!]]]'],
769+
['!}'],
770+
['!,}foo,]'],
771+
['! [!]'],
772+
];
773+
}
774+
775+
/**
776+
* @dataProvider quotedExclamationMarkProvider
777+
*/
778+
public function testQuotedExclamationMark($expected, string $value)
779+
{
780+
$this->assertSame($expected, Inline::parse($value));
781+
}
782+
783+
// This provider should stay consistent with unquotedExclamationMarkThrowsProvider
784+
public function quotedExclamationMarkProvider()
785+
{
786+
return [
787+
['!', '"!"'],
788+
['! ', '"! "'],
789+
[' !', '" !"'],
790+
[' ! ', '" ! "'],
791+
[['!'], '["!"]'],
792+
[['! '], '["! "]'],
793+
[['!', 'foo'], '["!", "foo"]'],
794+
[['foo', '!', 'ccc'], '["foo", "!", "ccc"]'],
795+
[['foo' => '!'], '{foo: "!"}'],
796+
[['foo' => ' !'], '{foo: " !"}'],
797+
[['foo' => '!', 'bar' => 'ccc'], '{foo: "!", bar: "ccc"}'],
798+
[['bar' => 'ccc', 'foo' => '! '], '{bar: "ccc", foo: "! "}'],
799+
['!]]]', '"!]]]"'],
800+
['!}', '"!}"'],
801+
['!,}foo,]', '"!,}foo,]"'],
802+
[['!'], '! ["!"]'],
803+
];
804+
}
740805
}

0 commit comments

Comments
 (0)