Skip to content

Commit 608b770

Browse files
Merge branch '5.1'
* 5.1: [Validator] use "allowedVariables" to configure the ExpressionLanguageSyntax constraint [Security] Fixed AbstractToken::hasUserChanged() [PropertyAccess] fix merge [DI] fix typo
2 parents 6567abe + af444f8 commit 608b770

File tree

7 files changed

+81
-12
lines changed

7 files changed

+81
-12
lines changed

src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ private function httpClientThatHasTracedRequests($tracedRequests): TraceableHttp
172172

173173
foreach ($tracedRequests as $request) {
174174
$response = $httpClient->request($request['method'], $request['url'], $request['options'] ?? []);
175-
$response->getContent(false); // To avoid exception in ResponseTrait::doDestruct
175+
$response->getContent(false); // disables exceptions from destructors
176176
}
177177

178178
return $httpClient;

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
408408

409409
// handle uninitialized properties in PHP >= 7
410410
if (__FILE__ === $trace['file']
411-
&& $access[self::ACCESS_NAME] === $trace['function']
411+
&& $name === $trace['function']
412412
&& $object instanceof $trace['class']
413413
&& preg_match((sprintf('/Return value (?:of .*::\w+\(\) )?must be of (?:the )?type (\w+), null returned$/')), $e->getMessage(), $matches)
414414
) {
415-
throw new UninitializedPropertyException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', false === strpos(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: 'class').'@anonymous', $access[self::ACCESS_NAME], $matches[1]), 0, $e);
415+
throw new UninitializedPropertyException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', false === strpos(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: key(class_implements($object)) ?: 'class').'@anonymous', $name, $matches[1]), 0, $e);
416416
}
417417

418418
throw $e;

src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,13 @@ private function hasUserChanged(UserInterface $user): bool
270270
return true;
271271
}
272272

273-
$currentUserRoles = array_map('strval', (array) $this->user->getRoles());
274273
$userRoles = array_map('strval', (array) $user->getRoles());
275274

276-
if (\count($userRoles) !== \count($currentUserRoles) || \count($userRoles) !== \count(array_intersect($userRoles, $currentUserRoles))) {
275+
if ($this instanceof SwitchUserToken) {
276+
$userRoles[] = 'ROLE_PREVIOUS_ADMIN';
277+
}
278+
279+
if (\count($userRoles) !== \count($this->getRoleNames()) || \count($userRoles) !== \count(array_intersect($userRoles, $this->getRoleNames()))) {
277280
return true;
278281
}
279282

src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,28 @@ public function getUserChanges()
152152
*/
153153
public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user)
154154
{
155-
$token = new ConcreteToken(['ROLE_FOO']);
155+
$token = new ConcreteToken();
156+
$token->setAuthenticated(true);
157+
$this->assertTrue($token->isAuthenticated());
158+
159+
$token->setUser($user);
160+
$this->assertTrue($token->isAuthenticated());
161+
162+
$token->setUser($user);
163+
$this->assertTrue($token->isAuthenticated());
164+
}
165+
166+
public function testIsUserChangedWhenSerializing()
167+
{
168+
$token = new ConcreteToken(['ROLE_ADMIN']);
156169
$token->setAuthenticated(true);
157170
$this->assertTrue($token->isAuthenticated());
158171

172+
$user = new SerializableUser('wouter', ['ROLE_ADMIN']);
159173
$token->setUser($user);
160174
$this->assertTrue($token->isAuthenticated());
161175

176+
$token = unserialize(serialize($token));
162177
$token->setUser($user);
163178
$this->assertTrue($token->isAuthenticated());
164179
}
@@ -179,6 +194,56 @@ public function __toString(): string
179194
}
180195
}
181196

197+
class SerializableUser implements UserInterface, \Serializable
198+
{
199+
private $roles;
200+
private $name;
201+
202+
public function __construct($name, array $roles = [])
203+
{
204+
$this->name = $name;
205+
$this->roles = $roles;
206+
}
207+
208+
public function getUsername()
209+
{
210+
return $this->name;
211+
}
212+
213+
public function getPassword()
214+
{
215+
return '***';
216+
}
217+
218+
public function getRoles()
219+
{
220+
if (empty($this->roles)) {
221+
return ['ROLE_USER'];
222+
}
223+
224+
return $this->roles;
225+
}
226+
227+
public function eraseCredentials()
228+
{
229+
}
230+
231+
public function getSalt()
232+
{
233+
return null;
234+
}
235+
236+
public function serialize()
237+
{
238+
return serialize($this->name);
239+
}
240+
241+
public function unserialize($serialized)
242+
{
243+
$this->name = unserialize($serialized);
244+
}
245+
}
246+
182247
class ConcreteToken extends AbstractToken
183248
{
184249
private $credentials = 'credentials_value';

src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntax.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ class ExpressionLanguageSyntax extends Constraint
2929

3030
public $message = 'This value should be a valid expression.';
3131
public $service;
32-
public $validateNames = true;
33-
public $names = [];
32+
public $allowedVariables = null;
3433

3534
/**
3635
* {@inheritdoc}

src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntaxValidator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Validator\Constraint;
1717
use Symfony\Component\Validator\ConstraintValidator;
1818
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
19+
use Symfony\Component\Validator\Exception\UnexpectedValueException;
1920

2021
/**
2122
* @author Andrey Sevastianov <mrpkmail@gmail.com>
@@ -39,15 +40,15 @@ public function validate($expression, Constraint $constraint): void
3940
}
4041

4142
if (!\is_string($expression)) {
42-
throw new UnexpectedTypeException($expression, 'string');
43+
throw new UnexpectedValueException($expression, 'string');
4344
}
4445

4546
if (null === $this->expressionLanguage) {
4647
$this->expressionLanguage = new ExpressionLanguage();
4748
}
4849

4950
try {
50-
$this->expressionLanguage->lint($expression, ($constraint->validateNames ? ($constraint->names ?? []) : null));
51+
$this->expressionLanguage->lint($expression, $constraint->allowedVariables);
5152
} catch (SyntaxError $exception) {
5253
$this->context->buildViolation($constraint->message)
5354
->setParameter('{{ syntax_error }}', $this->formatValue($exception->getMessage()))

src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxTest.php renamed to src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxValidatorTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator;
1919
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
2020

21-
class ExpressionLanguageSyntaxTest extends ConstraintValidatorTestCase
21+
class ExpressionLanguageSyntaxValidatorTest extends ConstraintValidatorTestCase
2222
{
2323
/**
2424
* @var \PHPUnit\Framework\MockObject\MockObject|ExpressionLanguage
@@ -45,6 +45,7 @@ public function testExpressionValid(): void
4545

4646
$this->validator->validate($this->value, new ExpressionLanguageSyntax([
4747
'message' => 'myMessage',
48+
'allowedVariables' => [],
4849
]));
4950

5051
$this->assertNoViolation();
@@ -58,7 +59,6 @@ public function testExpressionWithoutNames(): void
5859

5960
$this->validator->validate($this->value, new ExpressionLanguageSyntax([
6061
'message' => 'myMessage',
61-
'validateNames' => false,
6262
]));
6363

6464
$this->assertNoViolation();
@@ -73,6 +73,7 @@ public function testExpressionIsNotValid(): void
7373

7474
$this->validator->validate($this->value, new ExpressionLanguageSyntax([
7575
'message' => 'myMessage',
76+
'allowedVariables' => [],
7677
]));
7778

7879
$this->buildViolation('myMessage')

0 commit comments

Comments
 (0)