Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2722cdb

Browse files
Merge branch '7.0' into 7.1
* 7.0: [HttpClient][Mailer] Revert "Let curl handle transfer encoding", use HTTP/1.1 for Mailgun Reviewed Catalan missing translations [AssetMapper] Upgrade importmap polyfill Fix typo: synchronous -> synchronously [Serializer] Check if exception message in test is correct Ibexa is sponsoring Symfony 5.4, thanks to them! \o/ [VarDumper] Fix `FFICaster` test to be platform-adaptable [String] Add `alias` case to `EnglishInflector` [FrameworkBundle] Throw runtime exception when trying to use asset-mapper while http-client is disabled [SecurityBundle] Remove unused memory users’ `name` attribute from the XSD [VarExporter] generate __doUnserialize() method in ProxyHelper::generateLazyProxy() Double check if pcntl function exists Add additional headers in Scaleway bridge [VarDumper] Fix FFI caster test [DependencyInjection] Add test coverage for `AutowireCallable::buildDefinition()`
2 parents 0af0679 + 3550977 commit 2722cdb

File tree

20 files changed

+189
-42
lines changed

20 files changed

+189
-42
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ public function load(array $configs, ContainerBuilder $container): void
344344
throw new LogicException('AssetMapper support cannot be enabled as the AssetMapper component is not installed. Try running "composer require symfony/asset-mapper".');
345345
}
346346

347-
$this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']));
347+
$this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']), $this->readConfigEnabled('http_client', $container, $config['http_client']));
348348
} else {
349349
$container->removeDefinition('cache.asset_mapper');
350350
}
@@ -1291,12 +1291,14 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co
12911291
}
12921292
}
12931293

1294-
private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled): void
1294+
private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled, bool $httpClientEnabled): void
12951295
{
12961296
$loader->load('asset_mapper.php');
12971297

1298-
if (!$assetEnabled) {
1299-
$container->removeDefinition('asset_mapper.asset_package');
1298+
if (!$httpClientEnabled) {
1299+
$container->register('asset_mapper.http_client', HttpClientInterface::class)
1300+
->addTag('container.error')
1301+
->addError('You cannot use the AssetMapper integration since the HttpClient component is not enabled. Try enabling the "framework.http_client" config option.');
13001302
}
13011303

13021304
$paths = $config['paths'];

src/Symfony/Bundle/FrameworkBundle/Resources/config/asset_mapper.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
])
5555
->alias(AssetMapperInterface::class, 'asset_mapper')
5656

57+
->alias('asset_mapper.http_client', 'http_client')
58+
5759
->set('asset_mapper.mapped_asset_factory', MappedAssetFactory::class)
5860
->args([
5961
service('asset_mapper.public_assets_path_resolver'),
@@ -197,7 +199,7 @@
197199
])
198200

199201
->set('asset_mapper.importmap.resolver', JsDelivrEsmResolver::class)
200-
->args([service('http_client')])
202+
->args([service('asset_mapper.http_client')])
201203

202204
->set('asset_mapper.importmap.renderer', ImportMapRenderer::class)
203205
->args([
@@ -212,12 +214,12 @@
212214
->set('asset_mapper.importmap.auditor', ImportMapAuditor::class)
213215
->args([
214216
service('asset_mapper.importmap.config_reader'),
215-
service('http_client'),
217+
service('asset_mapper.http_client'),
216218
])
217219
->set('asset_mapper.importmap.update_checker', ImportMapUpdateChecker::class)
218220
->args([
219221
service('asset_mapper.importmap.config_reader'),
220-
service('http_client'),
222+
service('asset_mapper.http_client'),
221223
])
222224

223225
->set('asset_mapper.importmap.command.require', ImportMapRequireCommand::class)

src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112

113113
<xsd:complexType name="user">
114114
<xsd:attribute name="identifier" type="xsd:string" />
115-
<xsd:attribute name="name" type="xsd:string" />
116115
<xsd:attribute name="password" type="xsd:string" />
117116
<xsd:attribute name="roles" type="xsd:string" />
118117
</xsd:complexType>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
class ImportMapRenderer
2929
{
3030
// https://generator.jspm.io/#S2NnYGAIzSvJLMlJTWEAAMYOgCAOAA
31-
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.8.2/dist/es-module-shims.js';
32-
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_INTEGRITY = 'sha384-+dzlBT6NPToF0UZu7ZUA6ehxHY8h/TxJOZxzNXKhFD+5He5Hbex+0AIOiSsEaokw';
31+
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js';
32+
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_INTEGRITY = 'sha384-ie1x72Xck445i0j4SlNJ5W5iGeL3Dpa0zD48MZopgWsjNB/lt60SuG1iduZGNnJn';
3333

3434
public function __construct(
3535
private readonly ImportMapGenerator $importMapGenerator,

src/Symfony/Component/DependencyInjection/Tests/Attribute/AutowireCallableTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,35 @@ public function testArrayCallableWithServiceOnly()
9393
self::assertEquals([new Reference('my_service'), '__invoke'], $attribute->value);
9494
self::assertFalse($attribute->lazy);
9595
}
96+
97+
public function testLazyAsArrayInDefinition()
98+
{
99+
$attribute = new AutowireCallable(callable: [Foo::class, 'myMethod'], lazy: 'my_lazy_class');
100+
101+
self::assertSame([Foo::class, 'myMethod'], $attribute->value);
102+
103+
$definition = $attribute->buildDefinition('my_value', 'my_custom_type', new \ReflectionParameter([Foo::class, 'myMethod'], 'myParameter'));
104+
105+
self::assertSame('my_lazy_class', $definition->getClass());
106+
self::assertTrue($definition->isLazy());
107+
}
108+
109+
public function testLazyIsFalseInDefinition()
110+
{
111+
$attribute = new AutowireCallable(callable: [Foo::class, 'myMethod'], lazy: false);
112+
113+
self::assertFalse($attribute->lazy);
114+
115+
$definition = $attribute->buildDefinition('my_value', 'my_custom_type', new \ReflectionParameter([Foo::class, 'myMethod'], 'myParameter'));
116+
117+
self::assertSame('my_custom_type', $definition->getClass());
118+
self::assertFalse($definition->isLazy());
119+
}
120+
}
121+
122+
class Foo
123+
{
124+
public function myMethod(callable $myParameter)
125+
{
126+
}
96127
}

src/Symfony/Component/HttpClient/CurlHttpClient.php

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

251251
if (isset($options['normalized_headers']['content-length'][0])) {
252252
$curlopts[\CURLOPT_INFILESIZE] = (int) substr($options['normalized_headers']['content-length'][0], \strlen('Content-Length: '));
253-
} elseif (!isset($options['normalized_headers']['transfer-encoding'])) {
254-
$curlopts[\CURLOPT_INFILESIZE] = -1;
253+
}
254+
if (!isset($options['normalized_headers']['transfer-encoding'])) {
255+
$curlopts[\CURLOPT_HTTPHEADER][] = 'Transfer-Encoding:'.(isset($curlopts[\CURLOPT_INFILESIZE]) ? '' : ' chunked');
255256
}
256257

257258
if ('POST' !== $method) {

src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ protected function doSendHttp(SentMessage $message): ResponseInterface
6161

6262
$endpoint = sprintf('%s/v3/%s/messages.mime', $this->getEndpoint(), urlencode($this->domain));
6363
$response = $this->client->request('POST', 'https://'.$endpoint, [
64+
'http_version' => '1.1',
6465
'auth_basic' => 'api:'.$this->key,
6566
'headers' => $headers,
6667
'body' => $body->bodyToIterable(),

src/Symfony/Component/Mailer/Bridge/Scaleway/Tests/Transport/ScalewayApiTransportTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public function testSend()
6969
$this->assertSame('attachment.txt', $body['attachments'][0]['name']);
7070
$this->assertSame('text/plain', $body['attachments'][0]['type']);
7171
$this->assertSame(base64_encode('some attachment'), $body['attachments'][0]['content']);
72+
$this->assertSame('Reply-To', $body['additional_headers'][0]['key']);
73+
$this->assertStringContainsString('[email protected]', $body['additional_headers'][0]['value']);
7274

7375
return new JsonMockResponse(['emails' => [['message_id' => 'foobar']]], [
7476
'http_code' => 200,
@@ -81,6 +83,7 @@ public function testSend()
8183
$mail->subject('Hello!')
8284
->to(new Address('[email protected]', 'Saif Eddin'))
8385
->from(new Address('[email protected]', 'Fabien'))
86+
->replyTo(new Address('[email protected]', 'Foo'))
8487
->text('Hello There!')
8588
->addPart(new DataPart('some attachment', 'attachment.txt', 'text/plain'));
8689

src/Symfony/Component/Mailer/Bridge/Scaleway/Transport/ScalewayApiTransport.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ private function getPayload(Email $email, Envelope $envelope): array
9999
if ($attachements = $this->prepareAttachments($email)) {
100100
$payload['attachments'] = $attachements;
101101
}
102+
if ($headers = $this->getCustomHeaders($email)) {
103+
$payload['additional_headers'] = $headers;
104+
}
102105

103106
return $payload;
104107
}
@@ -120,6 +123,24 @@ private function prepareAttachments(Email $email): array
120123
return $attachments;
121124
}
122125

126+
private function getCustomHeaders(Email $email): array
127+
{
128+
$headers = [];
129+
$headersToBypass = ['from', 'to', 'cc', 'bcc', 'subject', 'content-type', 'sender'];
130+
foreach ($email->getHeaders()->all() as $name => $header) {
131+
if (\in_array($name, $headersToBypass, true)) {
132+
continue;
133+
}
134+
135+
$headers[] = [
136+
'key' => $header->getName(),
137+
'value' => $header->getBodyAsString(),
138+
];
139+
}
140+
141+
return $headers;
142+
}
143+
123144
private function formatAddress(Address $address): array
124145
{
125146
$array = ['email' => $address->getAddress()];

src/Symfony/Component/Mailer/MailerInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Symfony\Component\Mime\RawMessage;
1616

1717
/**
18-
* Interface for mailers able to send emails synchronous and/or asynchronous.
18+
* Interface for mailers able to send emails synchronously and/or asynchronously.
1919
*
2020
* Implementations must support synchronous and asynchronous sending.
2121
*

src/Symfony/Component/Messenger/EventListener/DispatchPcntlSignalListener.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class DispatchPcntlSignalListener implements EventSubscriberInterface
2121
{
2222
public function onWorkerRunning(): void
2323
{
24+
if (!\function_exists('pcntl_signal_dispatch')) {
25+
return;
26+
}
27+
2428
pcntl_signal_dispatch();
2529
}
2630

src/Symfony/Component/Notifier/ChatterInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Symfony\Component\Notifier\Transport\TransportInterface;
1515

1616
/**
17-
* Interface for classes able to send chat messages synchronous and/or asynchronous.
17+
* Interface for classes able to send chat messages synchronously and/or asynchronously.
1818
*
1919
* @author Fabien Potencier <[email protected]>
2020
*/

src/Symfony/Component/Notifier/TexterInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Symfony\Component\Notifier\Transport\TransportInterface;
1515

1616
/**
17-
* Interface for classes able to send SMS messages synchronous and/or asynchronous.
17+
* Interface for classes able to send SMS messages synchronously and/or asynchronously.
1818
*
1919
* @author Fabien Potencier <[email protected]>
2020
*/

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,19 @@
6464
</trans-unit>
6565
<trans-unit id="17">
6666
<source>Too many failed login attempts, please try again later.</source>
67-
<target>Massa intents d'inici de sessió fallits, torneu-ho a provar més tard.</target>
67+
<target>Massa intents d'inici de sessió fallits, si us plau torneu-ho a provar més tard.</target>
6868
</trans-unit>
6969
<trans-unit id="18">
7070
<source>Invalid or expired login link.</source>
7171
<target>Enllaç d'inici de sessió no vàlid o caducat.</target>
7272
</trans-unit>
7373
<trans-unit id="19">
7474
<source>Too many failed login attempts, please try again in %minutes% minute.</source>
75-
<target>Massa intents d'inici de sessió fallits, torneu-ho a provar en %minutes% minut.</target>
75+
<target>Massa intents d'inici de sessió fallits, si us plau torneu-ho a provar en %minutes% minut.</target>
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">Massa intents fallits d'inici de sessió, torneu-ho a provar d'aquí a %minutes% minuts.</target>
79+
<target>Massa intents d'inici de sessió fallits, si us plau torneu-ho a provar en %minutes% minuts.</target>
8080
</trans-unit>
8181
</body>
8282
</file>

src/Symfony/Component/String/Inflector/EnglishInflector.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ final class EnglishInflector implements InflectorInterface
289289
// atlases (atlas)
290290
['salta', 5, true, true, 'atlases'],
291291

292+
// aliases (alias)
293+
['saila', 5, true, true, 'aliases'],
294+
292295
// irises (iris)
293296
['siri', 4, true, true, 'irises'],
294297

src/Symfony/Component/String/Tests/Inflector/EnglishInflectorTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ public static function pluralizeProvider()
317317
['hippocampus', 'hippocampi'],
318318
['campus', 'campuses'],
319319
['hardware', 'hardware'],
320+
['alias', 'aliases'],
320321

321322
// test casing: if the first letter was uppercase, it should remain so
322323
['Man', 'Men'],

src/Symfony/Component/VarDumper/Caster/FFICaster.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,21 @@ private static function castFFIPointer(Stub $stub, CType $type, ?CData $data = n
115115
private static function castFFIStringValue(CData $data): string|CutStub
116116
{
117117
$result = [];
118+
$ffi = \FFI::cdef(<<<C
119+
size_t zend_get_page_size(void);
120+
C);
118121

119-
for ($i = 0; $i < self::MAX_STRING_LENGTH; ++$i) {
122+
$pageSize = $ffi->zend_get_page_size();
123+
124+
// get cdata address
125+
$start = $ffi->cast('uintptr_t', $ffi->cast('char*', $data))->cdata;
126+
// accessing memory in the same page as $start is safe
127+
$max = min(self::MAX_STRING_LENGTH, ($start | ($pageSize - 1)) - $start);
128+
129+
for ($i = 0; $i < $max; ++$i) {
120130
$result[$i] = $data[$i];
121131

122-
if ("\0" === $result[$i]) {
132+
if ("\0" === $data[$i]) {
123133
return implode('', $result);
124134
}
125135
}

src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class FFICasterTest extends TestCase
2424
{
2525
use VarDumperTestTrait;
2626

27+
/**
28+
* @see FFICaster::MAX_STRING_LENGTH
29+
*/
30+
private const MAX_STRING_LENGTH = 255;
31+
2732
protected function setUp(): void
2833
{
2934
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && 'preload' === \ini_get('ffi.enable')) {
@@ -173,52 +178,46 @@ public function testCastCuttedPointerToChar()
173178
{
174179
$actualMessage = str_repeat('Hello World!', 30)."\0";
175180
$actualLength = \strlen($actualMessage);
176-
177-
$expectedMessage = 'Hello World!Hello World!Hello World!Hello World!'
178-
.'Hello World!Hello World!Hello World!Hello World!Hello World!Hel'
179-
.'lo World!Hello World!Hello World!Hello World!Hello World!Hello '
180-
.'World!Hello World!Hello World!Hello World!Hello World!Hello Wor'
181-
.'ld!Hello World!Hel';
181+
$expectedMessage = substr($actualMessage, 0, self::MAX_STRING_LENGTH);
182182

183183
$string = \FFI::cdef()->new('char['.$actualLength.']');
184184
$pointer = \FFI::addr($string[0]);
185185
\FFI::memcpy($pointer, $actualMessage, $actualLength);
186186

187+
// the max length is platform-dependent and can be less than 255,
188+
// so we need to cut the expected message to the maximum length
189+
// allowed by pages size of the current system
190+
$ffi = \FFI::cdef(<<<C
191+
size_t zend_get_page_size(void);
192+
C);
193+
194+
$pageSize = $ffi->zend_get_page_size();
195+
$start = $ffi->cast('uintptr_t', $ffi->cast('char*', $pointer))->cdata;
196+
$max = min(self::MAX_STRING_LENGTH, ($start | ($pageSize - 1)) - $start);
197+
$expectedMessage = substr($expectedMessage, 0, $max);
198+
187199
$this->assertDumpEquals(<<<PHP
188200
FFI\CData<char*> size 8 align 8 {
189201
cdata: "$expectedMessage"…
190202
}
191203
PHP, $pointer);
192204
}
193205

194-
/**
195-
* It is worth noting that such a test can cause SIGSEGV, as it breaks
196-
* into "foreign" memory. However, this is only theoretical, since
197-
* memory is allocated within the PHP process and almost always "garbage
198-
* data" will be read from the PHP process itself.
199-
*
200-
* If this test fails for some reason, please report it: We may have to
201-
* disable the dumping of strings ("char*") feature in VarDumper.
202-
*
203-
* @see FFICaster::castFFIStringValue()
204-
*/
205206
public function testCastNonTrailingCharPointer()
206207
{
207208
$actualMessage = 'Hello World!';
208209
$actualLength = \strlen($actualMessage);
209210

210-
$string = \FFI::cdef()->new('char['.$actualLength.']');
211+
$string = \FFI::cdef()->new('char['.($actualLength + 1).']');
211212
$pointer = \FFI::addr($string[0]);
212-
213213
\FFI::memcpy($pointer, $actualMessage, $actualLength);
214214

215-
// Remove automatically addition of the trailing "\0" and remove trailing "\0"
216215
$pointer = \FFI::cdef()->cast('char*', \FFI::cdef()->cast('void*', $pointer));
217216
$pointer[$actualLength] = "\x01";
218217

219218
$this->assertDumpMatchesFormat(<<<PHP
220219
FFI\CData<char*> size 8 align 8 {
221-
cdata: "$actualMessage%s"
220+
cdata: %A"$actualMessage%s"
222221
}
223222
PHP, $pointer);
224223
}

0 commit comments

Comments
 (0)