8000 Merge branch '7.1' into 7.2 · symfony/symfony@7b41875 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7b41875

Browse files
Merge branch '7.1' into 7.2
* 7.1: [Process] minor fix [Process] Fix finding executables independently of open_basedir [HttpKernel] Skip logging uncaught exceptions in ErrorHandler, assume $kernel->terminateWithException() will do it [Serializer] Fix for method named `get()` [Notifier][TurboSMS] Process partial accepted response from transport parse empty sequence elements as null [HttpClient] Fix setting CURLMOPT_MAXCONNECTS throw a meaningful exception when parsing dotenv files with BOM [FrameworkBundle] Fix schema & finish incomplete tests for lock & semaphore config [Cache] Fix RedisSentinel params types [FrameworkBundle] Fix service reset between tests [Uid][Serializer][Validator] Mention RFC 9562 make sure temp files can be cleaned up on Windows
2 parents f91514d + 6ce42d9 commit 7b41875

File tree

38 files changed

+352
-28
lines changed

38 files changed

+352
-28
lines changed

.github/workflows/integration-tests.yml

+9-2
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,19 @@ jobs:
122122
image: dunglas/frankenphp:1.1.0
123123
ports:
124124
- 80:80
125+
- 8681:81
126+
- 8682:82
127+
- 8683:83
128+
- 8684:84
125129
volumes:
126130
- ${{ github.workspace }}:/symfony
127131
env:
128-
SERVER_NAME: 'http://localhost'
132+
SERVER_NAME: 'http://localhost http://localhost:81 http://localhost:82 http://localhost:83 http://localhost:84'
129133
CADDY_SERVER_EXTRA_DIRECTIVES: |
130-
root * /symfony/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/
134+
route /http-client* {
135+
root * /symfony/src/Symfony/Component/HttpClient/Tests/Fixtures/response-functional/
136+
php_server
137+
}
131138
132139
steps:
133140
- name: Checkout

src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php

+5
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ protected static function ensureKernelShutdown()
121121
static::$kernel->shutdown();
122122
static::$booted = false;
123123

124+
if ($container->has('services_resetter')) {
125+
// Instantiate the service because Container::reset() only resets services that have been used
126+
$container->get('services_resetter');
127+
}
128+
124129
if ($container instanceof ResetInterface) {
125130
$container->reset();
126131
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'annotations' => false,
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'php_errors' => ['log' => true],
8+
'lock' => null,
9+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
$container->setParameter('env(REDIS_DSN)', 'redis://paas.com');
4+
5+
$container->loadFromExtension('framework', [
6+
'annotations' => false,
7+
'http_method_override' => false,
8+
'handle_all_throwables' => true,
9+
'php_errors' => ['log' => true],
10+
'lock' => [
11+
'foo' => 'semaphore',
12+
'bar' => 'flock',
13+
'baz' => ['semaphore', 'flock'],
14+
'qux' => '%env(REDIS_DSN)%',
15+
],
16+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'annotations' => false,
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'php_errors' => ['log' => true],
8+
'semaphore' => 'redis://localhost',
9+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
$container->setParameter('env(REDIS_DSN)', 'redis://paas.com');
4+
5+
$container->loadFromExtension('framework', [
6+
'annotations' => false,
7+
'http_method_override' => false,
8+
'handle_all_throwables' => true,
9+
'php_errors' => ['log' => true],
10+
'semaphore' => [
11+
'foo' => 'redis://paas.com',
12+
'qux' => '%env(REDIS_DSN)%',
13+
],
14+
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/lock.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<framework:config http-method-override="false" handle-all-throwables="true">
99
<framework:annotations enabled="false" />
1010
<framework:php-errors log="true" />
11-
<framework:lock/>
11+
<framework:lock>
12+
<framework:resource>semaphore</framework:resource>
13+
</framework:lock>
1214
</framework:config>
1315
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/lock_named.xml

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
66
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
77

8-
98
<parameters>
109
<parameter key="env(REDIS_URL)">redis://paas.com</parameter>
1110
</parameters>
@@ -18,7 +17,7 @@
1817
<framework:resource name="bar">flock</framework:resource>
1918
<framework:resource name="baz">semaphore</framework:resource>
2019
<framework:resource name="baz">flock</framework:resource>
21-
<framework:resource name="qux">%env(REDIS_URL)%</framework:resource>
20+
<framework:resource name="qux">%env(REDIS_DSN)%</framework:resource>
2221
</framework:lock>
2322
</framework:config>
2423
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/semaphore.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<framework:config http-method-override="false" handle-all-throwables="true">
99
<framework:annotations enabled="false" />
1010
<framework:php-errors log="true" />
11-
<framework:semaphore/>
11+
<framework:semaphore>
12+
<framework:resource>redis://localhost</framework:resource>
13+
</framework:semaphore>
1214
</framework:config>
1315
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config http-method-override="false" handle-all-throwables="true">
9+
<framework:annotations enabled="false" />
10+
<framework:php-errors log="true" />
11+
<framework:semaphore>
12+
<framework:resource name="foo">redis://paas.com</framework:resource>
13+
<framework:resource name="qux">%env(REDIS_DSN)%</framework:resource>
14+
</framework:semaphore>
15+
</framework:config>
16+
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

+56
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,62 @@ public function testAssetMapperWithoutAssets()
23932393
$this->assertFalse($container->has('assets._default_package'));
23942394
}
23952395

2396+
public function testDefaultLock()
2397+
{
2398+
$container = $this->createContainerFromFile('lock');
2399+
2400+
self::assertTrue($container->hasDefinition('lock.default.factory'));
2401+
$storeDef = $container->getDefinition($container->getDefinition('lock.default.factory')->getArgument(0));
2402+
self::assertEquals(new Reference('semaphore'), $storeDef->getArgument(0));
2403+
}
2404+
2405+
public function testNamedLocks()
2406+
{
2407+
$container = $this->createContainerFromFile('lock_named');
2408+
2409+
self::assertTrue($container->hasDefinition('lock.foo.factory'));
2410+
$storeDef = $container->getDefinition($container->getDefinition('lock.foo.factory')->getArgument(0));
2411+
self::assertEquals(new Reference('semaphore'), $storeDef->getArgument(0));
2412+
2413+
self::assertTrue($container->hasDefinition('lock.bar.factory'));
2414+
$storeDef = $container->getDefinition($container->getDefinition('lock.bar.factory')->getArgument(0));
2415+
self::assertEquals(new Reference('flock'), $storeDef->getArgument(0));
2416+
2417+
self::assertTrue($container->hasDefinition('lock.baz.factory'));
2418+
$storeDef = $container->getDefinition($container->getDefinition('lock.baz.factory')->getArgument(0));
2419+
self::assertIsArray($storeDefArg = $storeDef->getArgument(0));
2420+
$storeDef1 = $container->getDefinition($storeDefArg[0]);
2421+
$storeDef2 = $container->getDefinition($storeDefArg[1]);
2422+
self::assertEquals(new Reference('semaphore'), $storeDef1->getArgument(0));
2423+
self::assertEquals(new Reference('flock'), $storeDef2->getArgument(0));
2424+
2425+
self::assertTrue($container->hasDefinition('lock.qux.factory'));
2426+
$storeDef = $container->getDefinition($container->getDefinition('lock.qux.factory')->getArgument(0));
2427+
self::assertStringContainsString('REDIS_DSN', $storeDef->getArgument(0));
2428+
}
2429+
2430+
public function testDefaultSemaphore()
2431+
{
2432+
$container = $this->createContainerFromFile('semaphore');
2433+
2434+
self::assertTrue($container->hasDefinition('semaphore.default.factory'));
2435+
$storeDef = $container->getDefinition($container->getDefinition('semaphore.default.factory')->getArgument(0));
2436+
self::assertSame('redis://localhost', $storeDef->getArgument(0));
2437+
}
2438+
2439+
public function testNamedSemaphores()
2440+
{
2441+
$container = $this->createContainerFromFile('semaphore_named');
2442+
2443+
self::assertTrue($container->hasDefinition('semaphore.foo.factory'));
2444+
$storeDef = $container->getDefinition($container->getDefinition('semaphore.foo.factory')->getArgument(0));
2445+
self::assertSame('redis://paas.com', $storeDef->getArgument(0));
2446+
2447+
self::assertTrue($container->hasDefinition('semaphore.qux.factory'));
2448+
$storeDef = $container->getDefinition($container->getDefinition('semaphore.qux.factory')->getArgument(0));
2449+
self::assertStringContainsString('REDIS_DSN', $storeDef->getArgument(0));
2450+
}
2451+
23962452
protected function createContainer(array $data = [])
23972453
{
23982454
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer;
13+
14+
class ResettableService
15+
{
16+
private $count = 0;
17+
18+
public function myCustomName(): void
19+
{
20+
++$this->count;
21+
}
22+
23+
public function getCount(): int
24+
{
25+
return $this->count;
26+
}
27+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/TestServiceContainer/services.yml

+5
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ services:
2323
decorates: decorated
2424
properties:
2525
inner: '@.inner'
26+
27+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\ResettableService:
28+
public: true
29+
tags:
30+
- kernel.reset: { method: 'myCustomName' }

src/Symfony/Bundle/FrameworkBundle/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"ext-xml": "*",
2222
"symfony/cache": "^6.4|^7.0",
2323
"symfony/config": "^6.4|^7.0",
24-
"symfony/dependency-injection": "^7.1",
24+
"symfony/dependency-injection": "^7.1.5",
2525
"symfony/deprecation-contracts": "^2.5|^3",
2626
"symfony/error-handler": "^6.4|^7.0",
2727
"symfony/event-dispatcher": "^6.4|^7.0",

src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static function setUpBeforeClass(): void
3232
self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.');
3333
}
3434

35-
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['redis_sentinel' => $service, 'prefix' => 'prefix_']);
35+
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']&timeout=0&retry_interval=0&read_timeout=0', ['redis_sentinel' => $service, 'prefix' => 'prefix_']);
3636
}
3737

3838
public function testInvalidDSNHasBothClusterAndSentinel()

src/Symfony/Component/Cache/Traits/RedisTrait.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
238238
$options = [
239239
'host' => $host,
240240
'port' => $port,
241-
'connectTimeout' => $params['timeout'],
241+
'connectTimeout' => (float) $params['timeout'],
242242
'persistent' => $params['persistent_id'],
243-
'retryInterval' => $params['retry_interval'],
244-
'readTimeout' => $params['read_timeout'],
243+
'retryInterval' => (int) $params['retry_interval'],
244+
'readTimeout' => (float) $params['read_timeout'],
245245
];
246246

247247
if ($passAuth) {

src/Symfony/Component/DependencyInjection/Container.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ public function initialized(string $id): bool
276276
public function reset(): void
277277
{
278278
$services = $this->services + $this->privates;
279-
$this->services = $this->factories = $this->privates = [];
280279

281280
foreach ($services as $service) {
282281
try {
@@ -288,7 +287,7 @@ public function reset(): void
288287
}
289288
}
290289

291-
$this->envCache = [];
290+
$this->envCache = $this->services = $this->factories = $this->privates = [];
292291
}
293292

294293
/**

src/Symfony/Component/Dotenv/Dotenv.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,13 @@ private function doLoad(bool $overrideExistingVars, array $paths): void
552552
throw new PathException($path);
553553
}
554554

555-
$this->populate($this->parse(file_get_contents($path), $path), $overrideExistingVars);
555+
$data = file_get_contents($path);
556+
557+
if ("\xEF\xBB\xBF" === substr($data, 0, 3)) {
558+
throw new FormatException('Loading files starting with a byte-order-mark (BOM) is not supported.', new FormatExceptionContext($data, $path, 1, 0));
559+
}
560+
561+
$this->populate($this->parse($data, $path), $overrideExistingVars);
556562
}
557563
}
558564

src/Symfony/Component/Dotenv/Tests/DotenvTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -604,4 +604,14 @@ public function testBootEnv()
604604
$resetContext();
605605
rmdir($tmpdir);
606606
}
607+
608+
public function testExceptionWithBom()
609+
{
610+
$dotenv = new Dotenv();
611+
612+
$this->expectException(FormatException::class);
613+
$this->expectExceptionMessage('Loading files starting with a byte-order-mark (BOM) is not supported.');
614+
615+
$dotenv->load(__DIR__.'/fixtures/file_with_bom');
616+
}
607617
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FOO=BAR

src/Symfony/Component/Filesystem/Filesystem.php

+4
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,10 @@ public function dumpFile(string $filename, $content): void
673673
$this->rename($tmpFile, $filename, true);
674674
} finally {
675675
if (file_exists($tmpFile)) {
676+
if ('\\' === \DIRECTORY_SEPARATOR && !is_writable($tmpFile)) {
677+
self::box('chmod', $tmpFile, self::box('fileperms', $tmpFile) | 0200);
678+
}
679+
676680
self::box('unlink', $tmpFile);
677681
}
678682
}

src/Symfony/Component/Filesystem/Tests/FilesystemTest.php

+16
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,22 @@ public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile()
18131813
$this->assertFilePermissions(745, $filename);
18141814
}
18151815

1816+
public function testDumpFileCleansUpAfterFailure()
1817+
{
1818+
$targetFile = $this->workspace.'/dump-file';
1819+
$this->filesystem->touch($targetFile);
1820+
$this->filesystem->chmod($targetFile, 0444);
1821+
1822+
try {
1823+
$this->filesystem->dumpFile($targetFile, 'any content');
1824+
} catch (IOException $e) {
1825+
} finally {
1826+
$this->filesystem->chmod($targetFile, 0666);
1827+
}
1828+
1829+
$this->assertSame([$targetFile], glob($this->workspace.'/*'));
1830+
}
1831+
18161832
public function testReadFile()
18171833
{
18181834
$licenseFile = \dirname(__DIR__).'/LICENSE';

src/Symfony/Component/HttpClient/Internal/CurlClientState.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public function __construct(int $maxHostConnections, int $maxPendingPushes)
4949
if (\defined('CURLPIPE_MULTIPLEX')) {
5050
curl_multi_setopt($this->handle, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX);
5151
}
52-
if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) {
53-
$maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections;
52+
if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS') && 0 < $maxHostConnections) {
53+
$maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, $maxHostConnections) ? 4294967295 : $maxHostConnections;
5454
}
5555
if (\defined('CURLMOPT_MAXCONNECTS') && 0 < $maxHostConnections) {
5656
curl_multi_setopt($this->handle, \CURLMOPT_MAXCONNECTS, $maxHostConnections);

0 commit comments

Comments
 (0)
0