diff --git a/Tests/Transport/Serialization/PhpSerializerTest.php b/Tests/Transport/Serialization/PhpSerializerTest.php index c83606a5..7ff0a00c 100644 --- a/Tests/Transport/Serialization/PhpSerializerTest.php +++ b/Tests/Transport/Serialization/PhpSerializerTest.php @@ -33,21 +33,21 @@ public function testEncodedIsDecodable() public function testDecodingFailsWithMissingBodyKey() { + $serializer = $this->createPhpSerializer(); + $this->expectException(MessageDecodingFailedException::class); $this->expectExceptionMessage('Encoded envelope should have at least a "body", or maybe you should implement your own serializer'); - $serializer = $this->createPhpSerializer(); - $serializer->decode([]); } public function testDecodingFailsWithBadFormat() { + $serializer = $this->createPhpSerializer(); + $this->expectException(MessageDecodingFailedException::class); $this->expectExceptionMessageMatches('/Could not decode/'); - $serializer = $this->createPhpSerializer(); - $serializer->decode([ 'body' => '{"message": "bar"}', ]); @@ -55,11 +55,11 @@ public function testDecodingFailsWithBadFormat() public function testDecodingFailsWithBadBase64Body() { + $serializer = $this->createPhpSerializer(); + $this->expectException(MessageDecodingFailedException::class); $this->expectExceptionMessageMatches('/Could not decode/'); - $serializer = $this->createPhpSerializer(); - $serializer->decode([ 'body' => 'x', ]); @@ -67,16 +67,29 @@ public function testDecodingFailsWithBadBase64Body() public function testDecodingFailsWithBadClass() { + $serializer = $this->createPhpSerializer(); + $this->expectException(MessageDecodingFailedException::class); $this->expectExceptionMessageMatches('/class "ReceivedSt0mp" not found/'); - $serializer = $this->createPhpSerializer(); - $serializer->decode([ 'body' => 'O:13:"ReceivedSt0mp":0:{}', ]); } + public function testDecodingFailsForPropertyTypeMismatch() + { + $serializer = $this->createPhpSerializer(); + $encodedEnvelope = $serializer->encode(new Envelope(new DummyMessage('true'))); + // Simulate a change of property type in the code base + $encodedEnvelope['body'] = str_replace('s:4:\"true\"', 'b:1', $encodedEnvelope['body']); + + $this->expectException(MessageDecodingFailedException::class); + $this->expectExceptionMessageMatches('/Could not decode/'); + + $serializer->decode($encodedEnvelope); + } + public function testEncodedSkipsNonEncodeableStamps() { $serializer = $this->createPhpSerializer(); diff --git a/Transport/Serialization/PhpSerializer.php b/Transport/Serialization/PhpSerializer.php index b1cb42d7..f9cd992c 100644 --- a/Transport/Serialization/PhpSerializer.php +++ b/Transport/Serialization/PhpSerializer.php @@ -75,16 +75,14 @@ private function safelyUnserialize(string $contents): Envelope throw new MessageDecodingFailedException('Could not decode an empty message using PHP serialization.'); } - $signalingException = new MessageDecodingFailedException(sprintf('Could not decode message using PHP serialization: %s.', $contents)); - if ($this->acceptPhpIncompleteClass) { $prevUnserializeHandler = ini_set('unserialize_callback_func', null); } else { $prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback'); } - $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) { + $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler) { if (__FILE__ === $file) { - throw $signalingException; + throw new \ErrorException($msg, 0, $type, $file, $line); } return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false; @@ -93,13 +91,19 @@ private function safelyUnserialize(string $contents): Envelope try { /** @var Envelope */ $envelope = unserialize($contents); + } catch (\Throwable $e) { + if ($e instanceof MessageDecodingFailedException) { + throw $e; + } + + throw new MessageDecodingFailedException('Could not decode Envelope: '.$e->getMessage(), 0, $e); } finally { restore_error_handler(); ini_set('unserialize_callback_func', $prevUnserializeHandler); } if (!$envelope instanceof Envelope) { - throw $signalingException; + throw new MessageDecodingFailedException('Could not decode message into an Envelope.'); } if ($envelope->getMessage() instanceof \__PHP_Incomplete_Class) {