From d5179eedf1cb2946dbd760475ebf05c251ef6a6e Mon Sep 17 00:00:00 2001 From: Antonio Pauletich Date: Fri, 25 Aug 2023 19:27:05 +0200 Subject: [PATCH] [Mime] Fix email (de)serialization issues --- Part/DataPart.php | 2 +- Part/TextPart.php | 2 +- Tests/EmailTest.php | 30 ++++++++++++++++++++++++++++++ Tests/Fixtures/foo_attachment.txt | 1 + 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 Tests/Fixtures/foo_attachment.txt diff --git a/Part/DataPart.php b/Part/DataPart.php index b42ecb4..2e6fc7e 100644 --- a/Part/DataPart.php +++ b/Part/DataPart.php @@ -156,7 +156,7 @@ public function __wakeup() throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) { - if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name])) { + if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name]) && !$this->_parent[$name] instanceof File) { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } $r = new \ReflectionProperty(TextPart::class, $name); diff --git a/Part/TextPart.php b/Part/TextPart.php index 3b1eb8d..4bd24d6 100644 --- a/Part/TextPart.php +++ b/Part/TextPart.php @@ -226,7 +226,7 @@ private function chooseEncoding(): string public function __sleep(): array { // convert resources to strings for serialization - if (null !== $this->seekable || $this->body instanceof File) { + if (null !== $this->seekable) { $this->body = $this->getBody(); $this->seekable = null; } diff --git a/Tests/EmailTest.php b/Tests/EmailTest.php index c4f829d..b8cc736 100644 --- a/Tests/EmailTest.php +++ b/Tests/EmailTest.php @@ -658,4 +658,34 @@ public function testBodyCache() $body2 = $email->getBody(); $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.'); } + + public function testAttachmentBodyIsPartOfTheSerializationEmailPayloadWhenUsingAttachMethod() + { + $email = new Email(); + $email->attach(file_get_contents(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'foo_attachment.txt') ?: ''); + + $this->assertTrue(str_contains(serialize($email), 'foo_bar_xyz_123')); + } + + public function testAttachmentBodyIsNotPartOfTheSerializationEmailPayloadWhenUsingAttachFromPathMethod() + { + $email = new Email(); + $email->attachFromPath(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'foo_attachment.txt'); + + $this->assertFalse(str_contains(serialize($email), 'foo_bar_xyz_123')); + } + + public function testEmailsWithAttachmentsWhichAreAFileInstanceCanBeUnserialized() + { + $email = new Email(); + $email->attachFromPath(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'foo_attachment.txt'); + + $email = unserialize(serialize($email)); + $this->assertInstanceOf(Email::class, $email); + + $attachments = $email->getAttachments(); + + $this->assertCount(1, $attachments); + $this->assertStringContainsString('foo_bar_xyz_123', $attachments[0]->getBody()); + } } diff --git a/Tests/Fixtures/foo_attachment.txt b/Tests/Fixtures/foo_attachment.txt new file mode 100644 index 0000000..291b582 --- /dev/null +++ b/Tests/Fixtures/foo_attachment.txt @@ -0,0 +1 @@ +foo_bar_xyz_123