8000 Merge branch '3.4' into 4.4 · enflow/symfony@f72dd9c · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 10, 2022. It is now read-only.

Commit f72dd9c

Browse files
Merge branch '3.4' into 4.4
* 3.4: [PropertyAccess] fix tests [WebProfilerBundle] fix test remove assertions that can never be reached [PropertyAccess] Improve message of unitialized property in php 7.4 [HttpFoundation] Fixed session migration with custom cookie lifetime [ 10000 Serializer] Remove unused variable Allow URL-encoded special characters in basic auth part of URLs [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key [Validator] Add missing Ukrainian and Russian translations No need to reconnect the bags to the session Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular
2 parents a56f98c + 547c99e commit f72dd9c

File tree

17 files changed

+104
-20
lines changed

17 files changed

+104
-20
lines changed

src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private function updateCspHeaders(Response $response, array $nonces = []): array
124124
$headers = $this->getCspHeaders($response);
125125

126126
foreach ($headers as $header => $directives) {
127-
foreach (['script-src' => 'csp_script_nonce', 'style-src' => 'csp_style_nonce'] as $type => $tokenName) {
127+
foreach (['script-src' => 'csp_script_nonce', 'script-src-elem' => 'csp_script_nonce', 'style-src' => 'csp_style_nonce', 'style-src-elem' => 'csp_style_nonce'] as $type => $tokenName) {
128128
if ($this->authorizesInline($directives, $type)) {
129129
continue;
130130
}

src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function testOnKernelResponse($nonce, $expectedNonce, Request $request, R
4141
$this->assertFalse($response->headers->has('X-SymfonyProfiler-Style-Nonce'));
4242

4343
foreach ($expectedCsp as $header => $value) {
44-
$this->assertSame($value, $response->headers->get($header));
44+
$this->assertSame($value, $response->headers->get($header), $header);
4545
}
4646
}
4747

@@ -131,7 +131,7 @@ public function provideRequestAndResponsesForOnKernelResponse()
131131
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
132132
$this->createRequest(),
133133
$this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'']),
134-
['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
134+
['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
135135
],
136136
[
137137
$nonce,

src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ public function regenerate($destroy = false, $lifetime = null)
215215
return false;
216216
}
217217

218-
if (null !== $lifetime) {
218+
if (null !== $lifetime && $lifetime != ini_get('session.cookie_lifetime')) {
219+
$this->save();
219220
ini_set('session.cookie_lifetime', $lifetime);
221+
$this->start();
220222
}
221223

222224
if ($destroy) {
@@ -225,10 +227,6 @@ public function regenerate($destroy = false, $lifetime = null)
225227

226228
$isRegenerated = session_regenerate_id($destroy);
227229

228-
// The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it.
229-
// @see https://bugs.php.net/70013
230-
$this->loadSession();
231-
232230
if (null !== $this->emulateSameSite) {
233231
$originalCookie = SessionUtils::popSessionCookie(session_name(), session_id());
234232
if (null !== $originalCookie) {

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ public function testRegenerateDestroy()
120120
$this->assertEquals(11, $storage->getBag('attributes')->get('legs'));
121121
}
122122

123+
public function testRegenerateWithCustomLifetime()
124+
{
125+
$storage = $this->getStorage();
126+
$storage->start();
127+
$id = $storage->getId();
128+
$lifetime = 999999;
129+
$storage->getBag('attributes')->set('legs', 11);
130+
$storage->regenerate(false, $lifetime);
131+
$this->assertNotEquals($id, $storage->getId());
132+
$this->assertEquals(11, $storage->getBag('attributes')->get('legs'));
133+
$this->assertEquals($lifetime, ini_get('session.cookie_lifetime'));
134+
}
135+
123136
public function testSessionGlobalIsUpToDateAfterIdRegeneration()
124137
{
125138
$storage = $this->getStorage();

src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testGetDefaultThrowsOnNoConfiguredValue()
4444
$resolver->setDefined($option = 'foo');
4545

4646
$debug = new OptionsResolverIntrospector($resolver);
47-
$this->assertSame('bar', $debug->getDefault($option));
47+
$debug->getDefault($option);
4848
}
4949

5050
public function testGetDefaultThrowsOnNotDefinedOption()
@@ -54,7 +54,7 @@ public function testGetDefaultThrowsOnNotDefinedOption()
5454
$resolver = new OptionsResolver();
5555

5656
$debug = new OptionsResolverIntrospector($resolver);
57-
$this->assertSame('bar', $debug->getDefault('foo'));
57+
$debug->getDefault('foo');
5858
}
5959

6060
public function testGetLazyClosures()
@@ -75,7 +75,7 @@ public function testGetLazyClosuresThrowsOnNoConfiguredValue()
7575
$resolver->setDefined($option = 'foo');
7676

7777
$debug = new OptionsResolverIntrospector($resolver);
78-
$this->assertSame('bar', $debug->getLazyClosures($option));
78+
$debug->getLazyClosures($option);
7979
}
8080

8181
public function testGetLazyClosuresThrowsOnNotDefinedOption()
@@ -85,7 +85,7 @@ public function testGetLazyClosuresThrowsOnNotDefinedOption()
8585
$resolver = new OptionsResolver();
8686

8787
$debug = new OptionsResolverIntrospector($resolver);
88-
$this->assertSame('bar', $debug->getLazyClosures('foo'));
88+
$debug->getLazyClosures('foo');
8989
}
9090

9191
public function testGetAllowedTypes()

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
385385
} catch (\TypeError $e) {
386386
// handle uninitialized properties in PHP >= 7
387387
if (preg_match((sprintf('/^Return value of %s::%s\(\) must be of the type (\w+), null returned$/', preg_quote(\get_class($object)), $access[self::ACCESS_NAME])), $e->getMessage(), $matches)) {
388-
throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Have you forgotten to initialize a property or to make the return type nullable using "?%3$s" instead?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e);
388+
throw new AccessException(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"?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e);
389389
}
390390

391391
throw $e;
@@ -418,7 +418,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
418418
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
419419
$r = new \ReflectionProperty($matches[1], $matches[2]);
420420

421-
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%3$s". You should either initialize it or make it nullable using "?%3$s" instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e);
421+
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e);
422422
}
423423

424424
throw $e;

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public function testGetValueThrowsExceptionIfIndexNotFoundAndIndexExceptionsEnab
139139
public function testGetValueThrowsExceptionIfUninitializedProperty()
140140
{
141141
$this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException');
142-
$this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$uninitialized" is not readable because it is typed "string". You should either initialize it or make it nullable using "?string" instead.');
142+
$this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');
143143

144144
$this->propertyAccessor->getValue(new UninitializedProperty(), 'uninitialized');
145145
}
@@ -150,7 +150,7 @@ public function testGetValueThrowsExceptionIfUninitializedProperty()
150150
public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetter()
151151
{
152152
$this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException');
153-
$this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty::getUninitialized()" returned "null", but expected type "array". Have you forgotten to initialize a property or to make the return type nullable using "?array" instead?');
153+
$this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?');
154154

155155
$this->propertyAccessor->getValue(new UninitializedPrivateProperty(), 'uninitialized');
156156
}

src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
5858
private $enableConstructorExtraction;
5959
private $accessFlags;
6060

61+
private $arrayMutatorPrefixesFirst;
62+
private $arrayMutatorPrefixesLast;
63+
6164
/**
6265
* @param string[]|null $mutatorPrefixes
6366
* @param string[]|null $accessorPrefixes
@@ -70,6 +73,9 @@ public function __construct(array $mutatorPrefixes = null, array $accessorPrefix
7073
$this->arrayMutatorPrefixes = null !== $arrayMutatorPrefixes ? $arrayMutatorPrefixes : self::$defaultArrayMutatorPrefixes;
7174
$this->enableConstructorExtraction = $enableConstructorExtraction;
7275
$this->accessFlags = $accessFlags;
76+
77+
$this->arrayMutatorPrefixesFirst = array_merge($this->arrayMutatorPrefixes, array_diff($this->mutatorPrefixes, $this->arrayMutatorPrefixes));
78+
$this->arrayMutatorPrefixesLast = array_reverse($this->arrayMutatorPrefixesFirst);
7379
}
7480

7581
/**
@@ -405,7 +411,9 @@ private function getMutatorMethod(string $class, string $property): ?array
405411
$ucProperty = ucfirst($property);
406412
$ucSingulars = (array) Inflector::singularize($ucProperty);
407413

408-
foreach ($this->mutatorPrefixes as $prefix) {
414+
$mutatorPrefixes = \in_array($ucProperty, $ucSingulars, true) ? $this->arrayMutatorPrefixesLast : $this->arrayMutatorPrefixesFirst;
415+
416+
foreach ($mutatorPrefixes as $prefix) {
409417
$names = [$ucProperty];
410418
if (\in_array($prefix, $this->arrayMutatorPrefixes)) {
411419
$names = array_merge($names, $ucSingulars);

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public function testGetProperties()
7070
'realParent',
7171
'xTotals',
7272
'YT',
73+
'date',
7374
'c',
7475
'd',
7576
'e',
@@ -109,6 +110,7 @@ public function testGetPropertiesWithCustomPrefixes()
109110
'foo4',
110111
'foo5',
111112
'files',
113+
'date',
112114
'c',
113115
'd',
114116
'e',
@@ -173,6 +175,8 @@ public function typesProvider()
173175
['staticSetter', null],
174176
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy')]],
175177
['realParent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy')]],
178+
['date', [new Type(Type::BUILTIN_TYPE_OBJECT, false, \DateTime::class)]],
179+
['dates', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, \DateTime::class))]],
176180
];
177181
}
178182

src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,12 @@ public function getXTotals()
210210
public function getYT()
211211
{
212212
}
213+
214+
public function setDate(\DateTime $date)
215+
{
216+
}
217+
218+
public function addDate(\DateTime $date)
219+
{
220+
}
213221
}

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ private function validateAndDenormalize(string $currentClass, string $attribute,
482482
*/
483483
protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, $parameterName, $parameterData, array $context, $format = null)
484484
{
485-
if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) {
485+
if (null === $this->propertyTypeExtractor || null === $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) {
486486
return parent::denormalizeParameter($class, $parameter, $parameterName, $parameterData, $context, $format);
487487
}
488488

@@ -617,6 +617,7 @@ private function getCacheKey(?string $format, array $context)
617617
unset($context[$key]);
618618
}
619619
unset($context[self::EXCLUDE_FROM_CACHE_KEY]);
620+
unset($context[self::OBJECT_TO_POPULATE]);
620621
unset($context['cache_key']); // avoid artificially different keys
621622

622623
try {

src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ public function testDenormalizeStringCollectionDecodedFromXmlWithTwoChildren()
174174
$this->assertEquals('bar', $stringCollection->children[1]);
175175
}
176176

177+
public function testDenormalizeNotSerializableObjectToPopulate()
178+
{
179+
$normalizer = new AbstractObjectNormalizerDummy();
180+
$normalizedData = $normalizer->denormalize(['foo' => 'foo'], Dummy::class, null, [AbstractObjectNormalizer::OBJECT_TO_POPULATE => new NotSerializable()]);
181+
182+
$this->assertSame('foo', $normalizedData->foo);
183+
}
184+
177185
private function getDenormalizerForStringCollection()
178186
{
179187
$extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock();
@@ -448,3 +456,15 @@ public function setSerializer(SerializerInterface $serializer)
448456
$this->serializer = $serializer;
449457
}
450458
}
459+
460+
class NotSerializable
461+
{
462+
public function __sleep()
463+
{
< C2EE /code>464+
if (class_exists(\Error::class)) {
465+
throw new \Error('not serializable');
466+
}
467+
468+
throw new \Exception('not serializable');
469+
}
470+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class UrlValidator extends ConstraintValidator
2424
{
2525
const PATTERN = '~^
2626
(%s):// # protocol
27-
(([\_\.\pL\pN-]+:)?([\_\.\pL\pN-]+)@)? # basic auth
27+
(((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+)@)? # basic auth
2828
(
2929
([\pL\pN\pS\-\_\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
3030
| # or

src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@
370370
<source>This value is not a valid hostname.</source>
371371
<target>Значение не является корректным именем хоста.</target>
372372
</trans-unit>
373+
<trans-unit id="96">
374+
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
375+
<target>Количество элементов в этой коллекции должно быть кратным {{ compared_value }}.</target>
376+
</trans-unit>
377+
<trans-unit id="97">
378+
<source>This value should satisfy at least one of the following constraints:</source>
379+
<target>Значение должно удовлетворять как минимум одному из следующих ограничений:</target>
380+
</trans-unit>
381+
<trans-unit id="98">
382+
<source>Each element of this collection should satisfy its own set of constraints.</source>
383+
<target>Каждый элемент этой коллекции должен удовлетворять своему собственному набору ограничений.</target>
384+
</trans-unit>
373385
</body>
374386
</file>
375387
</xliff>

src/Symfony/Component/Validator/Resources/translations/validators.uk.xlf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,22 @@
366366
<source>This value should be between {{ min }} and {{ max }}.</source>
367367
<target>Значення має бути між {{ min }} та {{ max }}.</target>
368368
</trans-unit>
369+
<trans-unit id="95">
370+
<source>This value is not a valid hostname.</source>
371+
<target>Значення не є дійсним іменем хоста.</target>
372+
</trans-unit>
373+
<trans-unit id="96">
374+
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
375+
<target>Кількість елементів у цій колекції повинна бути кратною {{ compared_value }}.</target>
376+
</trans-unit>
377+
<trans-unit id="97">
378+
<source>This value should satisfy at least one of the following constraints:</source>
379+
<target>Значення повинно задовольняти хоча б одному з наступних обмежень:</target>
380+
</trans-unit>
381+
<trans-unit id="98">
382+
<source>Each element of this collection should satisfy its own set of constraints.</source>
383+
<target>Кожен елемент цієї колекції повинен задовольняти власному набору обмежень.</target>
384+
</trans-unit>
369385
</body>
370386
</file>
371387
</xliff>

src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ public function getValidUrls()
157157
['http://user.name:pass.word@symfony.com'],
158158
['http://user-name@symfony.com'],
159159
['http://user_name@symfony.com'],
160+
['http://u%24er:password@symfony.com'],
161+
['http://user:pa%24%24word@symfony.com'],
160162
['http://symfony.com?'],
161163
['http://symfony.com?query=1'],
162164
['http://symfony.com/?query=1'],
@@ -255,6 +257,8 @@ public function getInvalidUrls()
255257
['http://:password@@symfony.com'],
256258
['http://username:passwordsymfony.com'],
257259
['http://usern@me:password@symfony.com'],
260+
['http://nota%hex:password@symfony.com'],
261+
['http://username:nota%hex@symfony.com'],
258262
['http://example.com/exploit.html?<script>alert(1);</script>'],
259263
['http://example.com/exploit.html?hel lo'],
260264
['http://example.com/exploit.html?not_a%hex'],

src/Symfony/Component/Yaml/Inline.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ private static function evaluateScalar(string $scalar, int $flags, array $refere
615615
throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
616616
}
617617
if (self::$exceptionOnInvalidType) {
618-
throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
618+
throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
619619
}
620620

621621
return null;

0 commit comments

Comments
 (0)
0