Skip to content

Commit 8120f3f

Browse files
Merge branch '6.4' into 7.0
* 6.4: (28 commits) [Serializer] Fix `@method` annotation fix compatibility with Doctrine DBAL 4 ensure string type with mbstring func overloading enabled [HttpKernel] Fix quotes expectations in tests [Validator] updated Greek translation [Cache][HttpFoundation][Lock] Fix empty username/password for PDO PostgreSQL [HttpClient][WebProfilerBundle] Do not generate cURL command when files are uploaded render newline in front of all script elements fix test fixture fix tests [Cache] Fix property types in PdoAdapter PHP files cannot be executable without shebang [TwigBridge] Mark CodeExtension as @internal Remove full DSNs from exception messages [Yaml] Fix uid binary parsing Disable the "Copy as cURL" button when the debug info are disabled [HttpClient] Replace `escapeshellarg` to prevent overpassing `ARG_MAX` Fix missing `profile` option for console commands [HttpFoundation][Lock] Makes MongoDB adapters usable with `ext-mongodb` only [HttpKernel] Preventing error 500 when function putenv is disabled ...
2 parents f1bfd88 + 35703d1 commit 8120f3f

File tree

49 files changed

+678
-406
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+678
-406
lines changed

.github/workflows/integration-tests.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ jobs:
159159
echo COMPOSER_ROOT_VERSION=$COMPOSER_ROOT_VERSION >> $GITHUB_ENV
160160
161161
echo "::group::composer update"
162-
composer require --dev --no-update mongodb/mongodb
163162
composer update --no-progress --ansi
164163
echo "::endgroup::"
165164

.github/workflows/unit-tests.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,6 @@ jobs:
190190
exit 0
191191
fi
192192
193-
(cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb)
194-
(cd src/Symfony/Component/Lock; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb)
195-
196193
# matrix.mode = high-deps
197194
echo "$COMPONENTS" | xargs -n1 | parallel -j +3 "_run_tests {} 'cd {} && $COMPOSER_UP && $PHPUNIT$LEGACY'" || X=1
198195
@@ -211,8 +208,6 @@ jobs:
211208
git fetch --depth=2 origin $SYMFONY_VERSION
212209
git checkout -m FETCH_HEAD
213210
PATCHED_COMPONENTS=$(echo "$PATCHED_COMPONENTS" | xargs dirname | xargs -n1 -I{} bash -c "[ -e '{}/phpunit.xml.dist' ] && echo '{}'" | sort || true)
214-
(cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb)
215-
(cd src/Symfony/Component/Lock; composer require --dev --no-update mongodb/mongodb)
216211
if [[ $PATCHED_COMPONENTS ]]; then
217212
echo "::group::install phpunit"
218213
./phpunit install

src/Symfony/Bridge/Twig/Extension/CodeExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@
1818
/**
1919
* Twig extension relate to PHP code and used by the profiler and the default exception templates.
2020
*
21+
* This extension should only be used for debugging tools code
22+
* that is never executed in a production environment.
23+
*
2124
* @author Fabien Potencier <fabien@symfony.com>
25+
*
26+
* @internal
2227
*/
2328
final class CodeExtension extends AbstractExtension
2429
{

src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
2121
use Symfony\Component\DependencyInjection\Reference;
2222
use Symfony\Component\VarDumper\Caster\ReflectionCaster;
23-
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
2423

2524
/**
2625
* @author Nicolas Grekas <p@tchwork.com>

src/Symfony/Bundle/FrameworkBundle/EventListener/ConsoleProfilerListener.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ public static function getSubscribedEvents(): array
5959

6060
public function initialize(ConsoleCommandEvent $event): void
6161
{
62-
if (!$event->getInput()->getOption('profile')) {
62+
$input = $event->getInput();
63+
if (!$input->hasOption('profile') || !$input->getOption('profile')) {
6364
$this->profiler->disable();
6465

6566
return;

src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Messenger/DummyTask.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
#[AsCronTask(expression: '* * * * *', arguments: [1], schedule: 'dummy_task')]
99
#[AsCronTask(expression: '0 * * * *', timezone: 'Europe/Berlin', arguments: ['2'], schedule: 'dummy_task', method: 'method2')]
1010
#[AsPeriodicTask(frequency: 5, arguments: [3], schedule: 'dummy_task')]
11-
#[AsPeriodicTask(frequency: '1 day', from: '00:00:00', jitter: 60, arguments: ['4'], schedule: 'dummy_task', method: 'method4')]
11+
#[AsPeriodicTask(frequency: '1 day', from: '2023-10-25 09:59:00Z', jitter: 60, arguments: ['4'], schedule: 'dummy_task', method: 'method4')]
1212
class DummyTask
1313
{
1414
public static array $calls = [];
1515

16-
#[AsPeriodicTask(frequency: '1 hour', from: '09:00:00', until: '17:00:00', arguments: ['b' => 6, 'a' => '5'], schedule: 'dummy_task')]
17-
#[AsCronTask(expression: '0 0 * * *', arguments: ['7', 8], schedule: 'dummy_task')]
16+
#[AsPeriodicTask(frequency: '1 hour', from: '2023-10-26 09:00:00Z', until: '2023-10-26 17:00:00Z', arguments: ['b' => 6, 'a' => '5'], schedule: 'dummy_task')]
17+
#[AsCronTask(expression: '0 10 * * *', arguments: ['7', 8], schedule: 'dummy_task')]
1818
public function attributesOnMethod(string $a, int $b): void
1919
{
2020
self::$calls[__FUNCTION__][] = [$a, $b];

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SchedulerTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\BarMessage;
1515
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummySchedule;
16+
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyTask;
1617
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\FooMessage;
1718
use Symfony\Component\Clock\MockClock;
1819
use Symfony\Component\HttpKernel\KernelInterface;
20+
use Symfony\Component\Messenger\MessageBusInterface;
21+
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
1922
use Symfony\Component\Scheduler\Messenger\SchedulerTransport;
2023
use Symfony\Component\Scheduler\RecurringMessage;
2124

@@ -54,6 +57,36 @@ public function testScheduler()
5457
$this->assertSame([$foo, $bar, $foo, $bar], $fetchMessages(600.0));
5558
}
5659

60+
public function testAutoconfiguredScheduler()
61+
{
62+
$container = self::getContainer();
63+
$container->set('clock', $clock = new MockClock('2023-10-26T08:59:59Z'));
64+
65+
$this->assertTrue($container->get('receivers')->has('scheduler_dummy_task'));
66+
$this->assertInstanceOf(SchedulerTransport::class, $cron = $container->get('receivers')->get('scheduler_dummy_task'));
67+
$bus = $container->get(MessageBusInterface::class);
68+
69+
$getCalls = static function (float $sleep) use ($clock, $cron, $bus) {
70+
DummyTask::$calls = [];
71+
$clock->sleep($sleep);
72+
foreach ($cron->get() as $message) {
73+
$bus->dispatch($message->with(new ReceivedStamp('scheduler_dummy_task')));
74+
}
75+
76+
return DummyTask::$calls;
77+
};
78+
79+
$this->assertSame([], $getCalls(0));
80+
$this->assertSame(['__invoke' => [[1]], 'method2' => [['2']], 'attributesOnMethod' => [['5', 6]]], $getCalls(1));
81+
$this->assertSame(['__invoke' => [[3]]], $getCalls(5));
82+
$this->assertSame(['__invoke' => [[3]]], $getCalls(5));
83+
$calls = $getCalls(3595);
84+
$this->assertCount(779, $calls['__invoke']);
85+
$this->assertSame([['2']], $calls['method2']);
86+
$this->assertSame([['4']], $calls['method4']);
87+
$this->assertSame([['5', 6], ['7', 8]], $calls['attributesOnMethod']);
88+
}
89+
5790
protected static function createKernel(array $options = []): KernelInterface
5891
{
5992
return parent::createKernel(['test_case' => 'Scheduler'] + $options);

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
},
3535
"require-dev": {
3636
"doctrine/persistence": "^1.3|^2|^3",
37+
"dragonmantank/cron-expression": "^3.1",
3738
"seld/jsonlint": "^1.10",
3839
"symfony/asset": "^6.4|^7.0",
3940
"symfony/asset-mapper": "^6.4|^7.0",

src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public function render(string|array $entryPoint, array $attributes = []): string
9191
$scriptAttributes = $this->createAttributesString($attributes);
9292
$importMapJson = json_encode(['imports' => $importMap], \JSON_THROW_ON_ERROR | \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_HEX_TAG);
9393
$output .= <<<HTML
94+
9495
<script type="importmap"$scriptAttributes>
9596
$importMapJson
9697
</script>

src/Symfony/Component/Cache/Adapter/PdoAdapter.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
2525
private string $dsn;
2626
private string $driver;
2727
private string $serverVersion;
28-
private mixed $table = 'cache_items';
29-
private mixed $idCol = 'item_id';
30-
private mixed $dataCol = 'item_data';
31-
private mixed $lifetimeCol = 'item_lifetime';
32-
private mixed $timeCol = 'item_time';
33-
private mixed $username = '';
34-
private mixed $password = '';
35-
private mixed $connectionOptions = [];
28+
private string $table = 'cache_items';
29+
private string $idCol = 'item_id';
30+
private string $dataCol = 'item_data';
31+
private string $lifetimeCol = 'item_lifetime';
32+
private string $timeCol = 'item_time';
33+
private ?string $username = null;
34+
private ?string $password = null;
35+
private array $connectionOptions = [];
3636
private string $namespace;
3737

3838
/**

src/Symfony/Component/Console/Messenger/RunCommandContext.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
/**
1515
* @author Kevin Bond <kevinbond@gmail.com>
1616
*/
17-
final class RunCommandContext extends RunCommandMessage
17+
final class RunCommandContext
1818
{
19-
public function __construct(RunCommandMessage $message, public readonly int $exitCode, public readonly string $output)
20-
{
21-
parent::__construct($message->input, $message->throwOnFailure, $message->catchExceptions);
19+
public function __construct(
20+
public readonly RunCommandMessage $message,
21+
public readonly int $exitCode,
22+
public readonly string $output,
23+
) {
2224
}
2325
}

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ public function testFindInvalidNamespace()
352352
$this->expectException(NamespaceNotFoundException::class);
353353
$this->expectExceptionMessage('There are no commands defined in the "bar" namespace.');
354354

355-
(new Application)->findNamespace('bar');
355+
(new Application())->findNamespace('bar');
356356
}
357357

358358
public function testFindUniqueNameButNamespaceName()

src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ public function testTranslationFileIsValid($filePath)
3131

3232
/**
3333
* @dataProvider provideTranslationFiles
34-
*
35-
* @group Legacy
3634
*/
3735
public function testTranslationFileIsValidWithoutEntityLoader($filePath)
3836
{

src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111

1212
namespace Symfony\Component\HttpClient\DataCollector;
1313

14+
use Symfony\Component\HttpClient\Exception\TransportException;
1415
use Symfony\Component\HttpClient\HttpClientTrait;
1516
use Symfony\Component\HttpClient\TraceableHttpClient;
1617
use Symfony\Component\HttpFoundation\Request;
1718
use Symfony\Component\HttpFoundation\Response;
1819
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
1920
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
21+
use Symfony\Component\Process\Process;
2022
use Symfony\Component\VarDumper\Caster\ImgStub;
2123

2224
/**
@@ -193,27 +195,18 @@ private function getCurlCommand(array $trace): ?string
193195
$dataArg = [];
194196

195197
if ($json = $trace['options']['json'] ?? null) {
196-
if (!$this->argMaxLengthIsSafe($payload = self::jsonEncode($json))) {
197-
return null;
198-
}
199-
$dataArg[] = '--data '.escapeshellarg($payload);
198+
$dataArg[] = '--data-raw '.$this->escapePayload(self::jsonEncode($json));
200199
} elseif ($body = $trace['options']['body'] ?? null) {
201200
if (\is_string($body)) {
202-
if (!$this->argMaxLengthIsSafe($body)) {
203-
return null;
204-
}
201+
$dataArg[] = '--data-raw '.$this->escapePayload($body);
202+
} elseif (\is_array($body)) {
205203
try {
206-
$dataArg[] = '--data '.escapeshellarg($body);
207-
} catch (\ValueError) {
204+
$body = explode('&', self::normalizeBody($body));
205+
} catch (TransportException) {
208206
return null;
209207
}
210-
} elseif (\is_array($body)) {
211-
$body = explode('&', self::normalizeBody($body));
212208
foreach ($body as $value) {
213-
if (!$this->argMaxLengthIsSafe($payload = urldecode($value))) {
214-
return null;
215-
}
216-
$dataArg[] = '--data '.escapeshellarg($payload);
209+
$dataArg[] = '--data-raw '.$this->escapePayload(urldecode($value));
217210
}
218211
} else {
219212
return null;
@@ -230,6 +223,11 @@ private function getCurlCommand(array $trace): ?string
230223
break;
231224
}
232225

226+
if (str_starts_with('Due to a bug in curl ', $line)) {
227+
// When the curl client disables debug info due to a curl bug, we cannot build the command.
228+
return null;
229+
}
230+
233231
if ('' === $line || preg_match('/^[*<]|(Host: )/', $line)) {
234232
continue;
235233
}
@@ -250,13 +248,18 @@ private function getCurlCommand(array $trace): ?string
250248
return implode(" \\\n ", $command);
251249
}
252250

253-
/**
254-
* Let's be defensive : we authorize only size of 8kio on Windows for escapeshellarg() argument to avoid a fatal error.
255-
*
256-
* @see https://github.com/php/php-src/blob/9458f5f2c8a8e3d6c65cc181747a5a75654b7c6e/ext/standard/exec.c#L397
257-
*/
258-
private function argMaxLengthIsSafe(string $payload): bool
251+
private function escapePayload(string $payload): string
259252
{
260-
return \strlen($payload) < ('\\' === \DIRECTORY_SEPARATOR ? 8100 : 256000);
253+
static $useProcess;
254+
255+
if ($useProcess ??= class_exists(Process::class)) {
256+
return (new Process([$payload]))->getCommandLine();
257+
}
258+
259+
if ('\\' === \DIRECTORY_SEPARATOR) {
260+
return '"'.str_replace('"', '""', $payload).'"';
261+
}
262+
263+
return "'".str_replace("'", "'\\''", $payload)."'";
261264
}
262265
}

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,14 @@ public function request(string $method, string $url, array $options = []): Respo
203203
}
204204

205205
switch ($cryptoMethod = $options['crypto_method']) {
206-
case \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT: $cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
207-
case \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: $cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
208-
case \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: $cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
206+
case \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT:
207+
$cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
208+
// no break
209+
case \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT:
210+
$cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
211+
// no break
212+
case \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT:
213+
$cryptoMethod |= \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
209214
}
210215

211216
$context = [

src/Symfony/Component/HttpClient/Psr18Client.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,8 @@
2828
use Psr\Http\Message\UriFactoryInterface;
2929
use Psr\Http\Message\UriInterface;
3030
use Symfony\Component\HttpClient\Internal\HttplugWaitLoop;
31-
use Symfony\Component\HttpClient\Response\StreamableInterface;
32-
use Symfony\Component\HttpClient\Response\StreamWrapper;
3331
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
3432
use Symfony\Contracts\HttpClient\HttpClientInterface;
35-
use Symfony\Contracts\HttpClient\ResponseInterface as HttpClientResponseInterface;
3633
use Symfony\Contracts\Service\ResetInterface;
3734

3835
if (!interface_exists(ClientInterface::class)) {

0 commit comments

Comments
 (0)