* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Messenger\Transport\Serialization; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\MessageDecodingFailedException; use Symfony\Component\Messenger\Stamp\NonSendableStampInterface; /** * @author Ryan Weaver */ class PhpSerializer implements SerializerInterface { /** * {@inheritdoc} */ public function decode(array $encodedEnvelope): Envelope { if (empty($encodedEnvelope['body'])) { throw new MessageDecodingFailedException('Encoded envelope should have at least a "body".'); } if (false === strpos($encodedEnvelope['body'], '}', -1)) { $encodedEnvelope['body'] = base64_decode($encodedEnvelope['body']); } $serializeEnvelope = stripslashes($encodedEnvelope['body']); return $this->safelyUnserialize($serializeEnvelope); } /** * {@inheritdoc} */ public function encode(Envelope $envelope): array { $envelope = $envelope->withoutStampsOfType(NonSendableStampInterface::class); $body = addslashes(serialize($envelope)); if (!preg_match('//u', $body)) { $body = base64_encode($body); } return [ 'body' => $body, ]; } private function safelyUnserialize(string $contents) { $signalingException = new MessageDecodingFailedException(sprintf('Could not decode message using PHP serialization: %s.', $contents)); $prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback'); $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) { if (__FILE__ === $file) { throw $signalingException; } return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false; }); try { $meta = unserialize($contents); } finally { restore_error_handler(); ini_set('unserialize_callback_func', $prevUnserializeHandler); } return $meta; } /** * @internal */ public static function handleUnserializeCallback($class) { throw new MessageDecodingFailedException(sprintf('Message class "%s" not found during decoding.', $class)); } }