8000 Merge branch '4.4' into 5.4 · symfony/symfony@6d859d4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6d859d4

Browse files
Merge branch '4.4' into 5.4
* 4.4: cs fix [Messenger] Fix Doctrine transport on MySQL [Translator] Fix translator overlapse [Yaml] Improve test coverage in DumperTest and ParserTest [Mailer] Fix error message in case of an STMP error [HttpClient] Fix shared connections not being freed on PHP < 8 [HttpFoundation] Fix invalid ID not regenerated with native PHP file sessions [HttpClient] Fix memory leak when using StreamWrapper Bump Symfony version to 4.4.45 Update VERSION for 4.4.44 Update CONTRIBUTORS for 4.4.44 Update CHANGELOG for 4.4.44
2 parents a4e68c2 + e62c7b6 commit 6d859d4

File tree

17 files changed

+538
-181
lines changed

17 files changed

+538
-181
lines changed

CONTRIBUTORS.md

Lines changed: 114 additions & 57 deletions
Large diffs are not rendered by default.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function reset()
9999
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS);
100100
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION);
101101

102-
if (\defined('CURL_LOCK_DATA_CONNECT')) {
102+
if (\defined('CURL_LOCK_DATA_CONNECT') && \PHP_VERSION_ID >= 80000) {
103103
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT);
104104
}
105105
}

src/Symfony/Component/HttpClient/Response/StreamWrapper.php

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,18 @@ public static function createResource(ResponseInterface $response, HttpClientInt
6161
throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__));
6262
}
6363

64-
if (false === stream_wrapper_register('symfony', __CLASS__)) {
64+
static $registered = false;
65+
66+
if (!$registered = $registered || stream_wrapper_register(strtr(__CLASS__, '\\', '-'), __CLASS__)) {
6567
throw new \RuntimeException(error_get_last()['message'] ?? 'Registering the "symfony" stream wrapper failed.');
6668
}
6769

68-
try {
69-
$context = [
70-
' F438 ;client' => $client ?? $response,
71-
'response' => $response,
72-
];
73-
74-
return fopen('symfony://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])) ?: null;
75-
} finally {
76-
stream_wrapper_unregister('symfony');
77-
}
70+
$context = [
71+
'client' => $client ?? $response,
72+
'response' => $response,
73+
];
74+
75+
return fopen(strtr(__CLASS__, '\\', '-').'://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context]));
7876
}
7977

8078
public function getResponse(): ResponseInterface

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/StrictSessionHandler.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ public function __construct(\SessionHandlerInterface $handler)
3030
$this->handler = $handler;
3131
}
3232

33+
/**
34+
* Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
35+
*
36+
* @internal
37+
*/
38+
public function isWrapper(): bool
39+
{
40+
return $this->handler instanceof \SessionHandler;
41+
}
42+
3343
/**
3444
* @return bool
3545
*/

src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
1313

14+
use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
15+
1416
/**
1517
* @author Drak <drak@zikula.org>
1618
*/
@@ -22,7 +24,7 @@ public function __construct(\SessionHandlerInterface $handler)
2224
{
2325
$this->handler = $handler;
2426
$this->wrapper = $handler instanceof \SessionHandler;
25-
$this->saveHandlerName = $this->wrapper ? \ini_get('session.save_handler') : 'user';
27+
$this->saveHandlerName = $this->wrapper || ($handler instanceof StrictSessionHandler && $handler->isWrapper()) ? \ini_get('session.save_handler') : 'user';
2628
}
2729

2830
/**

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
16+
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
1517
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
1618

1719
/**
@@ -159,6 +161,23 @@ public function testUpdateTimestamp()
159161

160162
$this->proxy->updateTimestamp('id', 'data');
161163
}
164+
165+
/**
166+
* @dataProvider provideNativeSessionStorageHandler
167+
*/
168+
public function testNativeSessionStorageSaveHandlerName($handler)
169+
{
170+
$this->assertSame('files', (new NativeSessionStorage([], $handler))->getSaveHandler()->getSaveHandlerName());
171+
}
172+
173+
public function provideNativeSessionStorageHandler()
174+
{
175+
return [
176+
[new \SessionHandler()],
177+
[new StrictSessionHandler(new \SessionHandler())],
178+
[new SessionHandlerProxy(new StrictSessionHandler(new \SessionHandler()))],
179+
];
180+
}
162181
}
163182

164183
abstract class TestSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface

src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,7 @@ public function addAuthenticator(AuthenticatorInterface $authenticator): void
100100

101101
protected function doHeloCommand(): void
102102
{
103-
try {
104-
$response = $this->executeCommand(sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]);
105-
} catch (TransportExceptionInterface $e) {
106-
parent::doHeloCommand();
107-
108-
return;
109-
}
110-
111-
$capabilities = $this->getCapabilities($response);
103+
$capabilities = $this->callHeloCommand();
112104

113105
/** @var SocketStream $stream */
114106
$stream = $this->getStream();
@@ -122,25 +114,30 @@ protected function doHeloCommand(): void
122114
throw new TransportException('Unable to connect with STARTTLS.');
123115
}
124116

125-
try {
126-
$response = $this->executeCommand(sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]);
127-
$capabilities = $this->getCapabilities($response);
128-
} catch (TransportExceptionInterface $e) {
129-
parent::doHeloCommand();
130-
131-
return;
132-
}
117+
$capabilities = $this->callHeloCommand();
133118
}
134119

135120
if (\array_key_exists('AUTH', $capabilities)) {
136121
$this->handleAuth($capabilities['AUTH']);
137122
}
138123
}
139124

140-
private function getCapabilities(string $ehloResponse): array
125+
private function callHeloCommand(): array
141126
{
127+
try {
128+
$response = $this->executeCommand(sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]);
129+
} catch (TransportExceptionInterface $e) {
130+
try {
131+
parent::doHeloCommand();
132+
} catch (TransportExceptionInterface $ex) {
133+
if (!$ex->getCode()) {
134+
throw $e;
135+
}
136+
}
137+
}
138+
142139
$capabilities = [];
143-
$lines = explode("\r\n", trim($ehloResponse));
140+
$lines = explode("\r\n", trim($response));
144141
array_shift($lines);
145142
foreach ($lines as $line) {
146143
if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) {

src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,13 @@ private function assertResponseCode(string $response, array $codes): void
297297
throw new LogicException('You must set the expected response code.');
298298
}
299299

300-
if (!$response) {
301-
throw new TransportException(sprintf('Expected response code "%s" but got an empty response.', implode('/', $codes)));
302-
}
303-
304300
[$code] = sscanf($response, '%3d');
305301
$valid = \in_array($code, $codes);
306302

307-
if (!$valid) {
308-
throw new TransportException(sprintf('Expected response code "%s" but got code "%s", with message "%s".', implode('/', $codes), $code, trim($response)), $code);
303+
if (!$valid || !$response) {
304+
$codeStr = $code ? sprintf('code "%s"', $code) : 'empty code';
305+
$responseStr = $response ? sprintf(', with message "%s"', trim($response)) : '';
306+
throw new TransportException(sprintf('Expected response code "%s" but got ', implode('/', $codes), $codeStr).$codeStr.$responseStr.'.', $code);
309307
}
310308
}
311309

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function get(): ?array
158158
{
159159
if ($this->driverConnection->getDatabasePlatform() instanceof MySQLPlatform) {
160160
try {
161-
$this->driverConnection->delete($this->configuration['table_name'], ['delivered_at' => '9999-12-31']);
161+
$this->driverConnection->delete($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59']);
162162
} catch (DriverException $e) {
163163
// Ignore the exception
164164
}
@@ -252,7 +252,7 @@ public function ack(string $id): bool
252252
{
253253
try {
254254
if ($this->driverConnection->getDatabasePlatform() instanceof MySQLPlatform) {
255-
return $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31'], ['id' => $id]) > 0;
255+
return $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59'], ['id' => $id]) > 0;
256256
}
257257

258258
return $this->driverConnection->delete($this->configuration['table_name'], ['id' => $id]) > 0;
@@ -265,7 +265,7 @@ public function reject(string $id): bool
265265
{
266266
try {
267267
if ($this->driverConnection->getDatabasePlatform() instanceof MySQLPlatform) {
268-
return $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31'], ['id' => $id]) > 0;
268+
return $this->driverConnection->update($this->configuration['table_name'], ['delivered_at' => '9999-12-31 23:59:59'], ['id' => $id]) > 0;
269269
}
270270

271271
return $this->driverConnection->delete($this->configuration['table_name'], ['id' => $id]) > 0;

src/Symfony/Component/Translation/MessageCatalogue.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,14 @@ public function replace(array $messages, string $domain = 'messages')
155155
*/
156156
public function add(array $messages, string $domain = 'messages')
157157
{
158-
if (!isset($this->messages[$domain])) {
159-
$this->messages[$domain] = [];
160-
}
161-
$intlDomain = $domain;
162-
if (!str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
163-
$intlDomain .= self::INTL_DOMAIN_SUFFIX;
164-
}
158+
$altDomain = str_ends_with($domain, self::INTL_DOMAIN_SUFFIX) ? substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX)) : $domain.self::INTL_DOMAIN_SUFFIX;
165159
foreach ($messages as $id => $message) {
166-
if (isset($this->messages[$intlDomain]) && \array_key_exists($id, $this->messages[$intlDomain])) {
167-
$this->messages[$intlDomain][$id] = $message;
168-
} else {
169-
$this->messages[$domain][$id] = $message;
170-
}
160+
unset($this->messages[$altDomain][$id]);
161+
$this->messages[$domain][$id] = $message;
162+
}
163+
164+
if ([] === ($this->messages[$altDomain] ?? null)) {
165+
unset($this->messages[$altDomain]);
171166
}
172167
}
173168

src/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function testGetResultFromIntlDomain()
5757
{
5858
$this->assertEquals(
5959
new MessageCatalogue('en', [
60-
'messages' => ['a' => 'old_a', 'b' => 'old_b'],
60+
'messages' => ['b' => 'old_b'],
6161
'messages+intl-icu' => ['d' => 'old_d', 'c' => 'new_c', 'a' => 'new_a'],
6262
]),
6363
$this->createOperation(

src/Symfony/Component/Translation/Tests/Catalogue/TargetOperationTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ public function testGetResultWithMixedDomains()
7171
{
7272
$this->assertEquals(
7373
new MessageCatalogue('en', [
74-
'messages' => ['a' => 'old_a'],
7574
'messages+intl-icu' => ['a' => 'new_a'],
7675
]),
7776
$this->createOperation(
@@ -103,7 +102,6 @@ public function testGetResultWithMixedDomains()
103102

104103
$this->assertEquals(
105104
new MessageCatalogue('en', [
106-
'messages' => ['a' => 'old_a'],
107105
'messages+intl-icu' => ['b' => 'new_b', 'a' => 'new_a'],
108106
]),
109107
$this->createOperation(

src/Symfony/Component/Translation/Tests/TranslatorTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
use Symfony\Component\Translation\Exception\InvalidArgumentException;
1616
use Symfony\Component\Translation\Exception\NotFoundResourceException;
1717
use Symfony\Component\Translation\Exception\RuntimeException;
18+
use Symfony\Component\Translation\Formatter\IntlFormatter;
19+
use Symfony\Component\Translation\Formatter\IntlFormatterInterface;
20+
use Symfony\Component\Translation\Formatter\MessageFormatter;
21+
use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
1822
use Symfony\Component\Translation\Loader\ArrayLoader;
1923
use Symfony\Component\Translation\MessageCatalogue;
2024
use Symfony\Component\Translation\Translator;
@@ -559,6 +563,26 @@ public function testIntlFormattedDomain()
559563
$this->assertSame('Hi Bob', $translator->trans('some_message', ['%name%' => 'Bob']));
560564
}
561565

566+
public function testIntlDomainOverlapseWithIntlResourceBefore()
567+
{
568+
$intlFormatterMock = $this->createMock(IntlFormatterInterface::class);
569+
$intlFormatterMock->expects($this->once())->method('formatIntl')->with('hello intl', 'en', [])->willReturn('hello intl');
570+
571+
$messageFormatter = new MessageFormatter(null, $intlFormatterMock);
572+
573+
$translator = new Translator('en', $messageFormatter);
574+
$translator->addLoader('array', new ArrayLoader());
575+
576+
$translator->addResource('array', ['some_message' => 'hello intl'], 'en', 'messages+intl-icu');
577+
$translator->addResource('array', ['some_message' => 'hello'], 'en', 'messages');
578+
579+
$this->assertSame('hello', $translator->trans('some_message', [], 'messages'));
580+
581+
$translator->addResource('array', ['some_message' => 'hello intl'], 'en', 'messages+intl-icu');
582+
583+
$this->assertSame('hello intl', $translator->trans('some_message', [], 'messages'));
584+
}
585+
562586
public function testMissingLoaderForResourceError()
563587
{
564588
$this->expectException(RuntimeException::class);

0 commit comments

Comments
 (0)
0