Skip to content

Commit f82e84f

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: [Mime] Fix invalid DKIM signature with multiple parts Fix Command::run phpdoc Update Response.php [HttpFoundation] Fix TypeError on null `$_SESSION` in `NativeSessionStorage::save()`
2 parents 5ee9668 + d5c67ce commit f82e84f

File tree

6 files changed

+46
-3
lines changed

6 files changed

+46
-3
lines changed

src/Symfony/Component/Console/Command/Command.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ protected function initialize(InputInterface $input, OutputInterface $output)
235235
*
236236
* @return int The command exit code
237237
*
238-
* @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}.
238+
* @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
239239
*
240240
* @see setCode()
241241
* @see execute()

src/Symfony/Component/HttpFoundation/Response.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class Response
7272
public const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
7373
public const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
7474
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
75-
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
75+
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; // RFC7725
7676
public const HTTP_INTERNAL_SERVER_ERROR = 500;
7777
public const HTTP_NOT_IMPLEMENTED = 501;
7878
public const HTTP_BAD_GATEWAY = 502;

src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public function save()
223223
unset($_SESSION[$key]);
224224
}
225225
}
226-
if ([$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) {
226+
if ($_SESSION && [$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) {
227227
unset($_SESSION[$key]);
228228
}
229229

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,13 @@ public function testRegenerateInvalidSessionIdForNativeFileSessionHandler()
311311
$this->assertTrue($started);
312312
$this->assertSame('&~[', session_id());
313313
}
314+
315+
public function testSaveHandlesNullSessionGracefully()
316+
{
317+
$storage = $this->getStorage();
318+
$_SESSION = null;
319+
$storage->save();
320+
321+
$this->addToAssertionCount(1);
322+
}
314323
}

src/Symfony/Component/Mime/Email.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class Email extends Message
5252

5353
private ?string $htmlCharset = null;
5454
private array $attachments = [];
55+
private ?AbstractPart $cachedBody = null; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries.
5556

5657
/**
5758
* @return $this
@@ -267,6 +268,7 @@ public function text($body, string $charset = 'utf-8'): static
267268
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
268269
}
269270

271+
$this->cachedBody = null;
270272
$this->text = $body;
271273
$this->textCharset = $charset;
272274

@@ -297,6 +299,7 @@ public function html($body, string $charset = 'utf-8'): static
297299
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
298300
}
299301

302+
$this->cachedBody = null;
300303
$this->html = $body;
301304
$this->htmlCharset = $charset;
302305

@@ -327,6 +330,7 @@ public function attach($body, string $name = null, string $contentType = null):
327330
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
328331
}
329332

333+
$this->cachedBody = null;
330334
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
331335

332336
return $this;
@@ -337,6 +341,7 @@ public function attach($body, string $name = null, string $contentType = null):
337341
*/
338342
public function attachFromPath(string $path, string $name = null, string $contentType = null): static
339343
{
344+
$this->cachedBody = null;
340345
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
341346

342347
return $this;
@@ -353,6 +358,7 @@ public function embed($body, string $name = null, string $contentType = null): s
353358
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
354359
}
355360

361+
$this->cachedBody = null;
356362
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
357363

358364
return $this;
@@ -363,6 +369,7 @@ public function embed($body, string $name = null, string $contentType = null): s
363369
*/
364370
public function embedFromPath(string $path, string $name = null, string $contentType = null): static
365371
{
372+
$this->cachedBody = null;
366373
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
367374

368375
return $this;
@@ -373,6 +380,7 @@ public function embedFromPath(string $path, string $name = null, string $content
373380
*/
374381
public function attachPart(DataPart $part): static
375382
{
383+
$this->cachedBody = null;
376384
$this->attachments[] = ['part' => $part];
377385

378386
return $this;
@@ -431,6 +439,10 @@ public function ensureValidity()
431439
*/
432440
private function generateBody(): AbstractPart
433441
{
442+
if (null !== $this->cachedBody) {
443+
return $this->cachedBody;
444+
}
445+
434446
$this->ensureValidity();
435447

436448
[$htmlPart, $attachmentParts, $inlineParts] = $this->prepareParts();
@@ -456,6 +468,8 @@ private function generateBody(): AbstractPart
456468
}
457469
}
458470

471+
$this->cachedBody = $part;
472+
459473
return $part;
460474
}
461475

src/Symfony/Component/Mime/Tests/EmailTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,4 +532,24 @@ public function testTextBodyAcceptedTypes()
532532
$email->text($contents);
533533
$this->assertSame($contents, $email->getTextBody());
534534
}
535+
536+
public function testBodyCache()
537+
{
538+
$email = new Email();
539+
$email->from('[email protected]');
540+
$email->to('[email protected]');
541+
$email->text('foo');
542+
$body1 = $email->getBody();
543+
$body2 = $email->getBody();
544+
$this->assertSame($body1, $body2, 'The two bodies must reference the same object, so the body cache ensures that the hash for the DKIM signature is unique.');
545+
546+
$email = new Email();
547+
$email->from('[email protected]');
548+
$email->to('[email protected]');
549+
$email->text('foo');
550+
$body1 = $email->getBody();
551+
$email->html('<b>bar</b>'); // We change a part to reset the body cache.
552+
$body2 = $email->getBody();
553+
$this->assertNotSame($body1, $body2, 'The two bodies must not reference the same object, so the body cache does not ensure that the hash for the DKIM signature is unique.');
554+
}
535555
}

0 commit comments

Comments
 (0)