Skip to content

Commit f456af9

Browse files
committed
Merge branch '7.3' into 7.4
* 7.3: [Messenger] Fix Oracle errors 'ORA-00955: Name is already used by an existing object' with Doctrine transport [String] Fix nodes singular [Console] Fix testing multiline question [Security][Validator] Review translations. [Security] Ignore target route when exiting impersonation [Console] Restore SHELL_VERBOSITY after a command is ran
2 parents 39e55e3 + c87fabb commit f456af9

File tree

14 files changed

+175
-37
lines changed

14 files changed

+175
-37
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ public function run(?InputInterface $input = null, ?OutputInterface $output = nu
186186
}
187187
}
188188

189+
$prevShellVerbosity = getenv('SHELL_VERBOSITY');
190+
189191
try {
190192
$this->configureIO($input, $output);
191193

@@ -223,6 +225,22 @@ public function run(?InputInterface $input = null, ?OutputInterface $output = nu
223225
$phpHandler[0]->setExceptionHandler($finalHandler);
224226
}
225227
}
228+
229+
// SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
230+
// to its previous value to avoid one command verbosity to spread to other commands
231+
if (false === $prevShellVerbosity) {
232+
if (\function_exists('putenv')) {
233+
@putenv('SHELL_VERBOSITY');
234+
}
235+
unset($_ENV['SHELL_VERBOSITY']);
236+
unset($_SERVER['SHELL_VERBOSITY']);
237+
} else {
238+
if (\function_exists('putenv')) {
239+
@putenv('SHELL_VERBOSITY='.$prevShellVerbosity);
240+
}
241+
$_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
242+
$_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
243+
}
226244
}
227245

228246
if ($this->autoExit) {

src/Symfony/Component/Console/Helper/QuestionHelper.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,16 @@ private function readInput($inputStream, Question $question): string|false
517517
$ret = '';
518518
$cp = $this->setIOCodepage();
519519
while (false !== ($char = fgetc($multiLineStreamReader))) {
520-
if (\PHP_EOL === "{$ret}{$char}") {
520+
if ("\x4" === $char || \PHP_EOL === "{$ret}{$char}") {
521521
break;
522522
}
523523
$ret .= $char;
524524
}
525525

526+
if (stream_get_meta_data($inputStream)['seekable']) {
527+
fseek($inputStream, ftell($multiLineStreamReader));
528+
}
529+
526530
return $this->resetIOCodepage($cp, $ret);
527531
}
528532

src/Symfony/Component/Console/Tester/ApplicationTester.php

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,37 +47,17 @@ public function __construct(
4747
*/
4848
public function run(array $input, array $options = []): int
4949
{
50-
$prevShellVerbosity = getenv('SHELL_VERBOSITY');
51-
52-
try {
53-
$this->input = new ArrayInput($input);
54-
if (isset($options['interactive'])) {
55-
$this->input->setInteractive($options['interactive']);
56-
}
50+
$this->input = new ArrayInput($input);
51+
if (isset($options['interactive'])) {
52+
$this->input->setInteractive($options['interactive']);
53+
}
5754

58-
if ($this->inputs) {
59-
$this->input->setStream(self::createStream($this->inputs));
60-
}
55+
if ($this->inputs) {
56+
$this->input->setStream(self::createStream($this->inputs));
57+
}
6158

62-
$this->initOutput($options);
59+
$this->initOutput($options);
6360

64-
return $this->statusCode = $this->application->run($this->input, $this->output);
65-
} finally {
66-
// SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
67-
// to its previous value to avoid one test's verbosity to spread to the following tests
68-
if (false === $prevShellVerbosity) {
69-
if (\function_exists('putenv')) {
70-
@putenv('SHELL_VERBOSITY');
71-
}
72-
unset($_ENV['SHELL_VERBOSITY']);
73-
unset($_SERVER['SHELL_VERBOSITY']);
74-
} else {
75-
if (\function_exists('putenv')) {
76-
@putenv('SHELL_VERBOSITY='.$prevShellVerbosity);
77-
}
78-
$_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
79-
$_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
80-
}
81-
}
61+
return $this->statusCode = $this->application->run($this->input, $this->output);
8262
}
8363
}

src/Symfony/Component/Console/Tester/TesterTrait.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ private static function createStream(array $inputs)
169169

170170
foreach ($inputs as $input) {
171171
fwrite($stream, $input.\PHP_EOL);
172+
173+
if (str_contains($input, \PHP_EOL)) {
174+
fwrite($stream, "\x4");
175+
}
172176
}
173177

174178
rewind($stream);

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

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
use Symfony\Component\Console\Input\InputDefinition;
4545
use Symfony\Component\Console\Input\InputInterface;
4646
use Symfony\Component\Console\Input\InputOption;
47+
use Symfony\Component\Console\Output\BufferedOutput;
4748
use Symfony\Component\Console\Output\ConsoleOutput;
4849
use Symfony\Component\Console\Output\NullOutput;
4950
use Symfony\Component\Console\Output\Output;
@@ -2472,6 +2473,102 @@ private function createSignalableApplication(Command $command, ?EventDispatcherI
24722473

24732474
return $application;
24742475
}
2476+
2477+
public function testShellVerbosityIsRestoredAfterCommandExecutionWithInitialValue()
2478+
{
2479+
// Set initial SHELL_VERBOSITY
2480+
putenv('SHELL_VERBOSITY=-2');
2481+
$_ENV['SHELL_VERBOSITY'] = '-2';
2482+
$_SERVER['SHELL_VERBOSITY'] = '-2';
2483+
2484+
$application = new Application();
2485+
$application->setAutoExit(false);
2486+
$application->register('foo')
2487+
->setCode(function (InputInterface $input, OutputInterface $output): int {
2488+
$output->write('SHELL_VERBOSITY: '.$_SERVER['SHELL_VERBOSITY']);
2489+
2490+
return 0;
2491+
});
2492+
2493+
$input = new ArrayInput(['command' => 'foo', '--verbose' => 3]);
2494+
$output = new BufferedOutput();
2495+
2496+
$application->run($input, $output);
2497+
2498+
$this->assertSame('SHELL_VERBOSITY: 3', $output->fetch());
2499+
$this->assertSame('-2', getenv('SHELL_VERBOSITY'));
2500+
$this->assertSame('-2', $_ENV['SHELL_VERBOSITY']);
2501+
$this->assertSame('-2', $_SERVER['SHELL_VERBOSITY']);
2502+
2503+
// Clean up for other tests
2504+
putenv('SHELL_VERBOSITY');
2505+
unset($_ENV['SHELL_VERBOSITY']);
2506+
unset($_SERVER['SHELL_VERBOSITY']);
2507+
}
2508+
2509+
public function testShellVerbosityIsRemovedAfterCommandExecutionWhenNotSetInitially()
2510+
{
2511+
// Ensure SHELL_VERBOSITY is not set initially
2512+
putenv('SHELL_VERBOSITY');
2513+
unset($_ENV['SHELL_VERBOSITY']);
2514+
unset($_SERVER['SHELL_VERBOSITY']);
2515+
2516+
$application = new Application();
2517+
$application->setAutoExit(false);
2518+
$application->register('foo')
2519+
->setCode(function (InputInterface $input, OutputInterface $output): int {
2520+
$output->write('SHELL_VERBOSITY: '.$_SERVER['SHELL_VERBOSITY']);
2521+
2522+
return 0;
2523+
});
2524+
2525+
$input = new ArrayInput(['command' => 'foo', '--verbose' => 3]);
2526+
$output = new BufferedOutput();
2527+
2528+
$application->run($input, $output);
2529+
2530+
$this->assertSame('SHELL_VERBOSITY: 3', $output->fetch());
2531+
$this->assertFalse(getenv('SHELL_VERBOSITY'));
2532+
$this->assertArrayNotHasKey('SHELL_VERBOSITY', $_ENV);
2533+
$this->assertArrayNotHasKey('SHELL_VERBOSITY', $_SERVER);
2534+
}
2535+
2536+
public function testShellVerbosityDoesNotLeakBetweenCommandExecutions()
2537+
{
2538+
// Ensure no initial SHELL_VERBOSITY
2539+
putenv('SHELL_VERBOSITY');
2540+
unset($_ENV['SHELL_VERBOSITY']);
2541+
unset($_SERVER['SHELL_VERBOSITY']);
2542+
2543+
$application = new Application();
2544+
$application->setAutoExit(false);
2545+
$application->register('verbose-cmd')
2546+
->setCode(function (InputInterface $input, OutputInterface $output): int {
2547+
$output->write('SHELL_VERBOSITY: '.$_SERVER['SHELL_VERBOSITY']);
2548+
2549+
return 0;
2550+
});
2551+
$application->register('normal-cmd')
2552+
->setCode(function (InputInterface $input, OutputInterface $output): int {
2553+
$output->write('SHELL_VERBOSITY: '.$_SERVER['SHELL_VERBOSITY']);
2554+
2555+
return 0;
2556+
});
2557+
2558+
$output = new BufferedOutput();
2559+
2560+
$application->run(new ArrayInput(['command' => 'verbose-cmd', '--verbose' => true]), $output);
2561+
2562+
$this->assertSame('SHELL_VERBOSITY: 1', $output->fetch(), 'SHELL_VERBOSITY should be set to 1 for verbose command');
2563+
$this->assertFalse(getenv('SHELL_VERBOSITY'), 'SHELL_VERBOSITY should not be set after first command');
2564+
2565+
$application->run(new ArrayInput(['command' => 'normal-cmd']), $output);
2566+
2567+
$this->assertSame('SHELL_VERBOSITY: 0', $output->fetch(), 'SHELL_VERBOSITY should not leak to second command');
2568+
$this->assertFalse(getenv('SHELL_VERBOSITY'), 'SHELL_VERBOSITY should not leak to second command');
2569+
$this->assertArrayNotHasKey('SHELL_VERBOSITY', $_ENV);
2570+
$this->assertArrayNotHasKey('SHELL_VERBOSITY', $_SERVER);
2571+
}
24752572
}
24762573

24772574
class CustomApplication extends Application

src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ public function testAskMultilineResponseWithWithCursorInMiddleOfSeekableInputStr
517517
$question->setMultiline(true);
518518

519519
$this->assertSame("some\ninput", $dialog->ask($this->createStreamableInputInterfaceMock($response), $this->createOutputInterface(), $question));
520-
$this->assertSame(8, ftell($response));
520+
$this->assertSame(18, ftell($response));
521521
}
522522

523523
#[DataProvider('getAskConfirmationData')]

src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,12 @@ public function testConfigureSchemaOracleSequenceNameSuffixed()
863863
{
864864
$driverConnection = $this->createMock(DBALConnection::class);
865865
$driverConnection->method('getDatabasePlatform')->willReturn(new OraclePlatform());
866+
867+
// Mock the result returned by executeQuery to be an Oracle version 12.1.0 or higher.
868+
$result = $this->createMock(Result::class);
869+
$result->method('fetchOne')->willReturn('12.1.0');
870+
$driverConnection->method('executeQuery')->willReturn($result);
871+
866872
$schema = new Schema();
867873

868874
$connection = new Connection(['table_name' => 'messenger_messages'], $driverConnection);

src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,9 @@ public function setup(): void
336336
throw new \TypeError(\sprintf('The table name must be an instance of "%s" or a string ("%s" given).', AbstractAsset::class, get_debug_type($tableName)));
337337
}
338338

339-
return $tableName === $this->configuration['table_name'];
339+
// SchemaAssetsFilter needs to match the messenger table name and also the messenger sequence name to make $schemaDiff work correctly in updateSchema()
340+
// This may also work for other databases if their sequence name is suffixed with '_seq', '_id_seq' or similar.
341+
return str_starts_with($tableName, $this->configuration['table_name']); // MESSENGER_MESSAGES*
340342
});
341343
$this->updateSchema();
342344
$configuration->setSchemaAssetsFilter($assetFilter);
@@ -567,9 +569,13 @@ private function addTableToSchema(Schema $schema): void
567569

568570
// We need to create a sequence for Oracle and set the id column to get the correct nextval
569571
if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) {
570-
$idColumn->setDefault($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX.'.nextval');
572+
$serverVersion = $this->driverConnection->executeQuery("SELECT version FROM product_component_version WHERE product LIKE 'Oracle Database%'")->fetchOne();
573+
if (version_compare($serverVersion, '12.1.0', '>=')) {
574+
$idColumn->setAutoincrement(false); // disable the creation of SEQUENCE and TRIGGER
575+
$idColumn->setDefault($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX.'.nextval');
571576

572-
$schema->createSequence($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX);
577+
$schema->createSequence($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX);
578+
}
573579
}
574580
}
575581

src/Symfony/Component/Security/Core/Resources/translations/security.es.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
</trans-unit>
7777
<trans-unit id="20">
7878
<source>Too many failed login attempts, please try again in %minutes% minutes.</source>
79-
<target state="needs-review-translation">Demasiados intentos fallidos de inicio de sesión, inténtelo de nuevo en %minutes% minutos.</target>
79+
<target>Demasiados intentos fallidos de inicio de sesión, inténtelo de nuevo en %minutes% minutos.</target>
8080
</trans-unit>
8181
</body>
8282
</file>

src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function authenticate(RequestEvent $event): void
111111
if (!$this->stateless) {
112112
$request->query->remove($this->usernameParameter);
113113
$request->server->set('QUERY_STRING', http_build_query($request->query->all(), '', '&'));
114-
$response = new RedirectResponse($this->urlGenerator && $this->targetRoute ? $this->urlGenerator->generate($this->targetRoute) : $request->getUri(), 302);
114+
$response = new RedirectResponse($this->urlGenerator && $this->targetRoute && self::EXIT_VALUE !== $username ? $this->urlGenerator->generate($this->targetRoute) : $request->getUri(), 302);
115115

116116
$event->setResponse($response);
117117
}

0 commit comments

Comments
 (0)