Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a492e72

Browse filesBrowse files
Merge branch '3.4' into 4.3
* 3.4: [Cache] fix memory leak when using PhpArrayAdapter fix parsing negative octal numbers [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass [Config] never try loading failed classes twice with ClassExistenceResource
2 parents 9a025b4 + c0b2ade commit a492e72
Copy full SHA for a492e72

File tree

13 files changed

+111
-32
lines changed
Filter options

13 files changed

+111
-32
lines changed

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function process(ContainerBuilder $container)
3131
}
3232

3333
$sessionOptions = $container->getParameter('session.storage.options');
34-
$domainRegexp = empty($sessionOptions['cookie_domain']) ? '%s' : sprintf('(?:%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));
34+
$domainRegexp = empty($sessionOptions['cookie_domain']) ? '%%s' : sprintf('(?:%%%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));
3535

3636
if ('auto' === ($sessionOptions['cookie_secure'] ?? null)) {
3737
$secureDomainRegexp = sprintf('{^https://%s$}i', $domainRegexp);

‎src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
+4-9Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,17 @@ static function ($key, $value, $isHit) {
6161
* This adapter takes advantage of how PHP stores arrays in its latest versions.
6262
*
6363
* @param string $file The PHP file were values are cached
64-
* @param CacheItemPoolInterface $fallbackPool Fallback when opcache is disabled
64+
* @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit
6565
*
6666
* @return CacheItemPoolInterface
6767
*/
6868
public static function create($file, CacheItemPoolInterface $fallbackPool)
6969
{
70-
// Shared memory is available in PHP 7.0+ with OPCache enabled
71-
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
72-
if (!$fallbackPool instanceof AdapterInterface) {
73-
$fallbackPool = new ProxyAdapter($fallbackPool);
74-
}
75-
76-
return new static($file, $fallbackPool);
70+
if (!$fallbackPool instanceof AdapterInterface) {
71+
$fallbackPool = new ProxyAdapter($fallbackPool);
7772
}
7873

79-
return $fallbackPool;
74+
return new static($file, $fallbackPool);
8075
}
8176

8277
/**

‎src/Symfony/Component/Cache/Simple/PhpArrayCache.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Simple/PhpArrayCache.php
+3-7Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,14 @@ public function __construct(string $file, Psr16CacheInterface $fallbackPool)
4141
/**
4242
* This adapter takes advantage of how PHP stores arrays in its latest versions.
4343
*
44-
* @param string $file The PHP file were values are cached
44+
* @param string $file The PHP file were values are cached
45+
* @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
4546
*
4647
* @return Psr16CacheInterface
4748
*/
4849
public static function create($file, Psr16CacheInterface $fallbackPool)
4950
{
50-
// Shared memory is available in PHP 7.0+ with OPCache enabled
51-
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
52-
return new static($file, $fallbackPool);
53-
}
54-
55-
return $fallbackPool;
51+
return new static($file, $fallbackPool);
5652
}
5753

5854
/**

‎src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public static function setUpBeforeClass(): void
6565

6666
protected function tearDown(): void
6767
{
68+
$this->createCachePool()->clear();
69+
6870
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
6971
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
7072
}

‎src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public static function setUpBeforeClass(): void
3737

3838
protected function tearDown(): void
3939
{
40+
$this->createCachePool()->clear();
41+
4042
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
4143
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
4244
}

‎src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public static function setUpBeforeClass(): void
5757

5858
protected function tearDown(): void
5959
{
60+
$this->createSimpleCache()->clear();
61+
6062
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
6163
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
6264
}

‎src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public static function setUpBeforeClass(): void
4444

4545
protected function tearDown(): void
4646
{
47+
$this->createSimpleCache()->clear();
48+
4749
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
4850
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
4951
}

‎src/Symfony/Component/Cache/Traits/PhpArrayTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Traits/PhpArrayTrait.php
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ trait PhpArrayTrait
2929
private $keys;
3030
private $values;
3131

32+
private static $valuesCache = [];
33+
3234
/**
3335
* Store an array of cached values.
3436
*
@@ -115,6 +117,7 @@ public function warmUp(array $values)
115117
unset($serialized, $value, $dump);
116118

117119
@rename($tmpFile, $this->file);
120+
unset(self::$valuesCache[$this->file]);
118121

119122
$this->initialize();
120123
}
@@ -127,6 +130,7 @@ public function clear()
127130
$this->keys = $this->values = [];
128131

129132
$cleared = @unlink($this->file) || !file_exists($this->file);
133+
unset(self::$valuesCache[$this->file]);
130134

131135
return $this->pool->clear() && $cleared;
132136
}
@@ -136,12 +140,15 @@ public function clear()
136140
*/
137141
private function initialize()
138142
{
139-
if (!file_exists($this->file)) {
143+
if (isset(self::$valuesCache[$this->file])) {
144+
$values = self::$valuesCache[$this->file];
145+
} elseif (!file_exists($this->file)) {
140146
$this->keys = $this->values = [];
141147

142148
return;
149+
} else {
150+
$values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []];
143151
}
144-
$values = (include $this->file) ?: [[], []];
145152

146153
if (2 !== \count($values) || !isset($values[0], $values[1])) {
147154
$this->keys = $this->values = [];

‎src/Symfony/Component/Config/Resource/ClassExistenceResource.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Resource/ClassExistenceResource.php
+37-8Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
3737
public function __construct(string $resource, bool $exists = null)
3838
{
3939
$this->resource = $resource;
40-
$this->exists = $exists;
40+
if (null !== $exists) {
41+
$this->exists = [(bool) $exists, null];
42+
}
4143
}
4244

4345
/**
@@ -65,26 +67,33 @@ public function isFresh($timestamp)
6567
{
6668
$loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
6769

68-
if (null !== $exists = &self::$existsCache[(int) (0 >= $timestamp)][$this->resource]) {
69-
$exists = $exists || $loaded;
70-
} elseif (!$exists = $loaded) {
70+
if (null !== $exists = &self::$existsCache[$this->resource]) {
71+
if ($loaded) {
72+
$exists = [true, null];
73+
} elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
74+
throw new \ReflectionException($exists[1]);
75+
}
76+
} elseif ([false, null] === $exists = [$loaded, null]) {
7177
if (!self::$autoloadLevel++) {
7278
spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
7379
}
7480
$autoloadedClass = self::$autoloadedClass;
7581
self::$autoloadedClass = ltrim($this->resource, '\\');
7682

7783
try {
78-
$exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
84+
$exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
7985
} catch (\Exception $e) {
86+
$exists[1] = $e->getMessage();
87+
8088
try {
8189
self::throwOnRequiredClass($this->resource, $e);
8290
} catch (\ReflectionException $e) {
8391
if (0 >= $timestamp) {
84-
unset(self::$existsCache[1][$this->resource]);
8592
throw $e;
8693
}
8794
}
95+
} catch (\Throwable $e) {
96+
$exists[1] = $e->getMessage();
8897
} finally {
8998
self::$autoloadedClass = $autoloadedClass;
9099
if (!--self::$autoloadLevel) {
@@ -97,7 +106,7 @@ public function isFresh($timestamp)
97106
$this->exists = $exists;
98107
}
99108

100-
return $this->exists xor !$exists;
109+
return $this->exists[0] xor !$exists[0];
101110
}
102111

103112
/**
@@ -112,6 +121,16 @@ public function __sleep(): array
112121
return ['resource', 'exists'];
113122
}
114123

124+
/**
125+
* @internal
126+
*/
127+
public function __wakeup()
128+
{
129+
if (\is_bool($this->exists)) {
130+
$this->exists = [$this->exists, null];
131+
}
132+
}
133+
115134
/**
116135
* Throws a reflection exception when the passed class does not exist but is required.
117136
*
@@ -147,7 +166,17 @@ public static function throwOnRequiredClass($class, \Exception $previous = null)
147166
throw $previous;
148167
}
149168

150-
$e = new \ReflectionException(sprintf('Class "%s" not found while loading "%s".', $class, self::$autoloadedClass), 0, $previous);
169+
$message = sprintf('Class "%s" not found.', $class);
170+
171+
if (self::$autoloadedClass !== $class) {
172+
$message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
173+
}
174+
175+
if (null !== $previous) {
176+
$message = $previous->getMessage();
177+
}
178+
179+
$e = new \ReflectionException($message, 0, $previous);
151180

152181
if (null !== $previous) {
153182
throw $e;
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Symfony\Component\Config\Tests\Fixtures;
4+
5+
class FileNameMismatchOnPurpose
6+
{
7+
}
8+
9+
throw new \RuntimeException('Mismatch between file name and class name.');

‎src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Config\Resource\ClassExistenceResource;
16+
use Symfony\Component\Config\Tests\Fixtures\BadFileName;
1617
use Symfony\Component\Config\Tests\Fixtures\BadParent;
1718
use Symfony\Component\Config\Tests\Fixtures\Resource\ConditionalClass;
1819

@@ -90,6 +91,24 @@ public function testBadParentWithNoTimestamp()
9091
$res->isFresh(0);
9192
}
9293

94+
public function testBadFileName()
95+
{
96+
$this->expectException('ReflectionException');
97+
$this->expectExceptionMessage('Mismatch between file name and class name.');
98+
99+
$res = new ClassExistenceResource(BadFileName::class, false);
100+
$res->isFresh(0);
101+
}
102+
103+
public function testBadFileNameBis()
104+
{
105+
$this->expectException('ReflectionException');
106+
$this->expectExceptionMessage('Mismatch between file name and class name.');
107+
108+
$res = new ClassExistenceResource(BadFileName::class, false);
109+
$res->isFresh(0);
110+
}
111+
93112
public function testConditionalClass()
94113
{
95114
$res = new ClassExistenceResource(ConditionalClass::class, false);

‎src/Symfony/Component/Yaml/Inline.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Inline.php
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,11 @@ private static function evaluateScalar(string $scalar, int $flags, array $refere
612612
// Optimize for returning strings.
613613
// no break
614614
case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]):
615+
if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
616+
$scalar = str_replace('_', '', (string) $scalar);
617+
}
618+
615619
switch (true) {
616-
case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar):
617-
$scalar = str_replace('_', '', (string) $scalar);
618-
// omitting the break / return as integers are handled in the next case
619-
// no break
620620
case ctype_digit($scalar):
621621
$raw = $scalar;
622622
$cast = (int) $scalar;
@@ -626,7 +626,7 @@ private static function evaluateScalar(string $scalar, int $flags, array $refere
626626
$raw = $scalar;
627627
$cast = (int) $scalar;
628628

629-
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
629+
return '0' == $scalar[1] ? -octdec(substr($scalar, 1)) : (($raw === (string) $cast) ? $cast : $raw);
630630
case is_numeric($scalar):
631631
case Parser::preg_match(self::getHexRegex(), $scalar):
632632
$scalar = str_replace('_', '', $scalar);

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Tests/InlineTest.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,20 @@ public function testUnfinishedInlineMap()
720720
$this->expectExceptionMessage('Unexpected end of line, expected one of ",}" at line 1 (near "{abc: \'def\'").');
721721
Inline::parse("{abc: 'def'");
722722
}
723+
724+
/**
725+
* @dataProvider getTestsForOctalNumbers
726+
*/
727+
public function testParseOctalNumbers($expected, $yaml)
728+
{
729+
self::assertSame($expected, Inline::parse($yaml));
730+
}
731+
732+
public function getTestsForOctalNumbers()
733+
{
734+
return [
735+
'positive octal number' => [28, '034'],
736+
'negative octal number' => [-28, '-034'],
737+
];
738+
}
723739
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.