8000 [Messenger] PhpSerializer: TypeError should throw MessageDecodingFail… · symfony/symfony@d896fbf · GitHub
[go: up one dir, main page]

Skip to content

Commit d896fbf

Browse files
committed
[Messenger] PhpSerializer: TypeError should throw MessageDecodingFailedException
Actually, the fix should handle more cases than only TypeError.
1 parent a67e8bd commit d896fbf

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
class DummyMessageTyped implements DummyMessageInterface
6+
{
7+
private string $message;
8+
9+
public function __construct(string $message)
10+
{
11+
$this->message = $message;
12+
}
13+
14+
public function getMessage(): string
15+
{
16+
return $this->message;
17+
}
18+
}

src/Symfony/Component/Messenger/Tests/Transport/Serialization/PhpSerializerTest.php

+32-15
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
1717
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
1818
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
19+
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageTyped;
1920
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2021

2122
class PhpSerializerTest extends TestCase
2223
{
23-
public function testEncodedIsDecodable()
24+
public function testEncodedIsDecodable(): void
2425
{
2526
$serializer = new PhpSerializer();
2627

@@ -31,53 +32,53 @@ public function testEncodedIsDecodable()
3132
$this->assertEquals($envelope, $serializer->decode($encoded));
3233
}
3334

34-
public function testDecodingFailsWithMissingBodyKey()
35+
public function testDecodingFailsWithMissingBodyKey(): void
3536
{
37+
$serializer = new PhpSerializer();
38+
3639
$this->expectException(MessageDecodingFailedException::class);
3740
$this->expectExceptionMessage('Encoded envelope should have at least a "body", or maybe you should implement your own serializer');
3841

39-
$serializer = new PhpSerializer();
40-
4142
$serializer->decode([]);
4243
}
4344

44-
public function testDecodingFailsWithBadFormat()
45+
public function testDecodingFailsWithBadFormat(): void
4546
{
47+
$serializer = new PhpSerializer();
48+
4649
$this->expectException(MessageDecodingFailedException::class);
4750
$this->expectExceptionMessageMatches('/Could not decode/');
4851

49-
$serializer = new PhpSerializer();
50-
5152
$serializer->decode([
5253
'body' => '{"message": "bar"}',
5354
]);
5455
}
5556

56-
public function testDecodingFailsWithBadBase64Body()
57+
public function testDecodingFailsWithBadBase64Body(): void
5758
{
59+
$serializer = new PhpSerializer();
60+
5861
$this->expectException(MessageDecodingFailedException::class);
5962
$this->expectExceptionMessageMatches('/Could not decode/');
6063

61-
$serializer = new PhpSerializer();
62-
6364
$serializer->decode([
6465
'body' => 'x',
6566
]);
6667
}
6768

68-
public function testDecodingFailsWithBadClass()
69+
public function testDecodingFailsWithBadClass(): void
6970
{
71+
$serializer = new PhpSerializer();
72+
7073
$this->expectException(MessageDecodingFailedException::class);
7174
$this->expectExceptionMessageMatches('/class "ReceivedSt0mp" not found/');
7275

73-
$serializer = new PhpSerializer();
74-
7576
$serializer->decode([
7677
'body' => 'O:13:"ReceivedSt0mp":0:{}',
7778
]);
7879
}
7980

80-
public function testEncodedSkipsNonEncodeableStamps()
81+
public function testEncodedSkipsNonEncodeableStamps(): void
8182
{
8283
$serializer = new PhpSerializer();
8384

@@ -89,7 +90,7 @@ public function testEncodedSkipsNonEncodeableStamps()
8990
$this->assertStringNotContainsString('DummyPhpSerializerNonSendableStamp', $encoded['body']);
9091
}
9192

92-
public function testNonUtf8IsBase64Encoded()
93+
public function testNonUtf8IsBase64Encoded(): void
9394
{
9495
$serializer = new PhpSerializer();
9596

@@ -99,6 +100,22 @@ public function testNonUtf8IsBase64Encoded()
99100
$this->assertTrue((bool) preg_match('//u', $encoded['body']), 'Encodes non-UTF8 payloads');
100101
$this->assertEquals($envelope, $serializer->decode($encoded));
101102
}
103+
104+
/**
105+
* @requires PHP >= 7.4
106+
*/
107+
public function testDecodingFailsForPropertyTypeMismatch(): void
108+
{
109+
$serializer = new Ph F438 pSerializer();
110+
$encodedEnvelope = $serializer->encode(new Envelope(new DummyMessageTyped('true')));
111+
// Simulate a change of property type in the code base
112+
$encodedEnvelope['body'] = str_replace('s:4:\"true\"', 'b:1', $encodedEnvelope['body']);
113+
114+
$this->expectException(MessageDecodingFailedException::class);
115+
$this->expectExceptionMessageMatches('/Could not unserialize/');
116+
117+
$serializer->decode($encodedEnvelope);
118+
}
102119
}
103120

104121
class DummyPhpSerializerNonSendableStamp implements NonSendableStampInterface

src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,20 @@ private function safelyUnserialize(string $contents)
7373
});
7474

7575
try {
76-
$meta = unserialize($contents);
76+
/** @var Envelope */
77+
$envelope = unserialize($contents);
78+
} catch (\Throwable $e) {
79+
if ($e instanceof MessageDecodingFailedException) {
80+
throw $e;
81+
}
82+
83+
throw new MessageDecodingFailedException('Could not unserialize Envelope: '.$e->getMessage(), 0, $e);
7784
} finally {
7885
restore_error_handler();
7986
ini_set('unserialize_callback_func', $prevUnserializeHandler);
8087
}
8188

82-
return $meta;
89+
return $envelope;
8390
}
8491

8592
/**

0 commit comments

Comments
 (0)
0