[Mailer] Azure API Transport - attachments are encoded twice
Symfony version(s) affected
7.1
Description
AzureApiTransport.php Line 163:
$attachment->bodyToString();
returns aGVsbG8gd29ybGQ=, which is already base64 encoded. This results in an attachment containing YUdWc2JHOGdkMjl5YkdRPQ== (see context), which is hello world encoded twice. Also affects other mime types like image/png.
How to reproduce
Example code:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Routing\Annotation\Route;
class MailerController extends AbstractController
{
#[Route('/email')]
public function sendEmail(MailerInterface $mailer): Response
{
$email = (new Email())
->from('[email protected]')
->to('[email protected]')
->addPart(new DataPart('hello world', 'test.txt', 'text/plain'));
$mailer->send($email);
}
}
Possible Solution
Removing base64_encode() from line 163 allows attachments to be sent correctly, not sure what the implications are for other encoding schemes like quoted-printable or 8bit.
'contentInBase64' => base64_encode(str_replace("\r\n", '', $attachment->bodyToString())),
Might be better to base64 encode the string from getBody() instead:
'contentInBase64' => base64_encode($attachment->getBody()),
(I usually work with Laravel, not very familiar with how Symfony works).
Additional Context
Raw message:
--=-RKMiR41T+m0J1Vs36aWDPA==
Content-Type: multipart/alternative; boundary="=-RTeuOYJLs2Fl6qsDDGsPrg=="
--=-RTeuOYJLs2Fl6qsDDGsPrg==
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
=C2=A9 2023. All rights reserved.
--=-RTeuOYJLs2Fl6qsDDGsPrg==--
--=-RKMiR41T+m0J1Vs36aWDPA==
Content-Type: text/plain; name=test.txt
Content-Disposition: attachment
Content-Transfer-Encoding: base64
Content-Id: <adbe2c0b-3174-400a-b47a-78090cb7ee7b>
YUdWc2JHOGdkMjl5YkdRPQ==
--=-RKMiR41T+m0J1Vs36aWDPA==--
I think it is better to use base64_encode on getBody() because this way we are sure to always use Base64. Using only bodyToString() may use another encoder which would not be valid in the case of Azure. I provided the fix and tests.
Thanks for reporting!