Skip to content

Commit 7235989

Browse files
committed
Merge branch '6.0' into 6.1
* 6.0: [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 5d9ad9f + f82e84f commit 7235989

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
@@ -252,7 +252,7 @@ protected function initialize(InputInterface $input, OutputInterface $output)
252252
*
253253
* @return int The command exit code
254254
*
255-
* @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}.
255+
* @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
256256
*
257257
* @see setCode()
258258
* @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;
@@ -440,6 +448,10 @@ private function ensureBodyValid(): void
440448
*/
441449
private function generateBody(): AbstractPart
442450
{
451+
if (null !== $this->cachedBody) {
452+
return $this->cachedBody;
453+
}
454+
443455
$this->ensureBodyValid();
444456

445457
[$htmlPart, $attachmentParts, $inlineParts] = $this->prepareParts();
@@ -465,6 +477,8 @@ private function generateBody(): AbstractPart
465477
}
466478
}
467479

480+
$this->cachedBody = $part;
481+
468482
return $part;
469483
}
470484

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,4 +540,24 @@ public function testTextBodyAcceptedTypes()
540540
$email->text($contents);
541541
$this->assertSame($contents, $email->getTextBody());
542542
}
543+
544+
public function testBodyCache()
545+
{
546+
$email = new Email();
547+
$email->from('[email protected]');
548+
$email->to('[email protected]');
549+
$email->text('foo');
550+
$body1 = $email->getBody();
551+
$body2 = $email->getBody();
552+
$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.');
553+
554+
$email = new Email();
555+
$email->from('[email protected]');
556+
$email->to('[email protected]');
557+
$email->text('foo');
558+
$body1 = $email->getBody();
559+
$email->html('<b>bar</b>'); // We change a part to reset the body cache.
560+
$body2 = $email->getBody();
561+
$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.');
562+
}
543563
}

0 commit comments

Comments
 (0)