Description
Symfony version(s) affected: 5.3.9
Description
There are some broken message bodies for which the PhpSerializer
format doesn't throw a MessageDecodingFailedException
, but a TypeError
:
In PhpSerializer.php line 38:
[TypeError]
Symfony\Component\Messenger\Transport\Serialization\PhpSerializer::decode(): Return value must be of type Symfony\Component\Messenger\Envelope, bool returned
Exception trace:
at /app/vendor/symfony/messenger/Transport/Serialization/PhpSerializer.php:38
Symfony\Component\Messenger\Transport\Serialization\PhpSerializer->decode() at /app/vendor/symfony/doctrine-messenger/Transport/DoctrineReceiver.php:160
Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineReceiver->createEnvelopeFromData() at /app/vendor/symfony/doctrine-messenger/Transport/DoctrineReceiver.php:70
Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineReceiver->get() at /app/vendor/symfony/doctrine-messenger/Transport/DoctrineTransport.php:45
Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport->get() at /app/vendor/symfony/messenger/Worker.php:88
Symfony\Component\Messenger\Worker->run() at /app/vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:209
Symfony\Component\Messenger\Command\ConsumeMessagesCommand->execute() at /app/vendor/symfony/console/Command/Command.php:299
Symfony\Component\Console\Command\Command->run() at /app/vendor/symfony/console/Application.php:996
Symfony\Component\Console\Application->doRunCommand() at /app/vendor/symfony/framework-bundle/Console/Application.php:96
Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /app/vendor/symfony/console/Application.php:295
Symfony\Component\Console\Application->doRun() at /app/vendor/symfony/framework-bundle/Console/Application.php:82
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /app/vendor/symfony/console/Application.php:167
Symfony\Component\Console\Application->run() at /app/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:56
Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at /app/vendor/autoload_runtime.php:35
require_once() at /app/bin/console:11
How to reproduce
- Use an async transport, like doctrine, with the PHP native serializer.
- Publish a message with the raw body
x
.
Possible Solution
This happens because PhpSerializer::decode()
executes base64_decode('x')
, which returns an empty string.
The empty string in turn is passed to PhpSerializer::safelyUnserialize()
, which calls unserialize('')
;
Unfortunately unserialize('')
simply returns false without triggering a warning, so the MessageDecodingFailedException
exception isn't thrown.
I'd suggest to add a specific check in PhpSerializer::safelyUnserialize()
to always throw when $encodedEnvelope
is empty string.
Additional context