Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f09f960

Browse filesBrowse files
BrokenSourceCodefabpot
BrokenSourceCode
authored andcommitted
[Mime] Fix invalid DKIM signature with multiple parts
1 parent bf46a8d commit f09f960
Copy full SHA for f09f960

File tree

2 files changed

+34
-0
lines changed
Filter options

2 files changed

+34
-0
lines changed

‎src/Symfony/Component/Mime/Email.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mime/Email.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Email extends Message
4343
private $html;
4444
private $htmlCharset;
4545
private $attachments = [];
46+
private ?AbstractPart $cachedBody = null; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries.
4647

4748
/**
4849
* @return $this
@@ -282,6 +283,7 @@ public function text($body, string $charset = 'utf-8')
282283
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
283284
}
284285

286+
$this->cachedBody = null;
285287
$this->text = $body;
286288
$this->textCharset = $charset;
287289

@@ -312,6 +314,7 @@ public function html($body, string $charset = 'utf-8')
312314
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
313315
}
314316

317+
$this->cachedBody = null;
315318
$this->html = $body;
316319
$this->htmlCharset = $charset;
317320

@@ -342,6 +345,7 @@ public function attach($body, string $name = null, string $contentType = null)
342345
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
343346
}
344347

348+
$this->cachedBody = null;
345349
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
346350

347351
return $this;
@@ -352,6 +356,7 @@ public function attach($body, string $name = null, string $contentType = null)
352356
*/
353357
public function attachFromPath(string $path, string $name = null, string $contentType = null)
354358
{
359+
$this->cachedBody = null;
355360
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
356361

357362
return $this;
@@ -368,6 +373,7 @@ public function embed($body, string $name = null, string $contentType = null)
368373
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
369374
}
370375

376+
$this->cachedBody = null;
371377
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
372378

373379
return $this;
@@ -378,6 +384,7 @@ public function embed($body, string $name = null, string $contentType = null)
378384
*/
379385
public function embedFromPath(string $path, string $name = null, string $contentType = null)
380386
{
387+
$this->cachedBody = null;
381388
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
382389

383390
return $this;
@@ -388,6 +395,7 @@ public function embedFromPath(string $path, string $name = null, string $content
388395
*/
389396
public function attachPart(DataPart $part)
390397
{
398+
$this->cachedBody = null;
391399
$this->attachments[] = ['part' => $part];
392400

393401
return $this;
@@ -446,6 +454,10 @@ public function ensureValidity()
446454
*/
447455
private function generateBody(): AbstractPart
448456
{
457+
if (null !== $this->cachedBody) {
458+
return $this->cachedBody;
459+
}
460+
449461
$this->ensureValidity();
450462

451463
[$htmlPart, $attachmentParts, $inlineParts] = $this->prepareParts();
@@ -471,6 +483,8 @@ private function generateBody(): AbstractPart
471483
}
472484
}
473485

486+
$this->cachedBody = $part;
487+
474488
return $part;
475489
}
476490

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mime/Tests/EmailTest.php
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,24 @@ public function testTextBodyAcceptedTypes()
458458
$email->text($contents);
459459
$this->assertSame($contents, $email->getTextBody());
460460
}
461+
462+
public function testBodyCache()
463+
{
464+
$email = new Email();
465+
$email->from('fabien@symfony.com');
466+
$email->to('fabien@symfony.com');
467+
$email->text('foo');
468+
$body1 = $email->getBody();
469+
$body2 = $email->getBody();
470+
$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.');
471+
472+
$email = new Email();
473+
$email->from('fabien@symfony.com');
474+
$email->to('fabien@symfony.com');
475+
$email->text('foo');
476+
$body1 = $email->getBody();
477+
$email->html('<b>bar</b>'); // We change a part to reset the body cache.
478+
$body2 = $email->getBody();
479+
$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.');
480+
}
461481
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.