Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Messenger] TypeError in PhpSerializer::decode() when message body is not valid #43566

Closed
@dsech

Description

@dsech

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

  1. Use an async transport, like doctrine, with the PHP native serializer.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions