symfony icon indicating copy to clipboard operation
symfony copied to clipboard

[Mailer] Azure API Transport - attachments are encoded twice

Open zaxbux opened this issue 2 years ago • 1 comments

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==--

zaxbux avatar Dec 19 '23 02:12 zaxbux

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!

alexandre-daubois avatar Dec 19 '23 15:12 alexandre-daubois