Skip to content

Commit d0c52e7

Browse files
Sniff Avro payloads in legacy serializer
1 parent ef29218 commit d0c52e7

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/Serializers/Serializer.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ private static function legacyUnserializeClass(string $blob): string
191191
return Base64::class;
192192
}
193193

194+
if (self::looksLikeAvro($blob)) {
195+
return Avro::class;
196+
}
197+
194198
// JSON blobs always start with "{", "[", a digit, quote, minus, "t"/"f"/"n".
195199
// PHP-serialized-closure blobs start with "O:".
196200
if ($blob !== '' && $blob[0] !== 'O' && self::looksLikeJson($blob)) {
@@ -211,6 +215,15 @@ private static function looksLikeJson(string $blob): bool
211215
}
212216
return in_array($blob, ['true', 'false', 'null'], true);
213217
}
218+
219+
private static function looksLikeAvro(string $blob): bool
220+
{
221+
$bytes = base64_decode($blob, true);
222+
223+
return $bytes !== false
224+
&& $bytes !== ''
225+
&& in_array($bytes[0], [Avro::PREFIX_GENERIC_WRAPPER, Avro::PREFIX_TYPED_SCHEMA], true);
226+
}
214227
}
215228

216229
/**

tests/Unit/Serializers/SerializeTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,46 @@ public function testSerializableReturnsFalseForClosure(): void
6565
}));
6666
}
6767

68+
public function testLegacyUnserializeSniffsAvroPayload(): void
69+
{
70+
config([
71+
'workflows.serializer' => 'avro',
72+
]);
73+
74+
$serialized = Serializer::serialize([
75+
'message' => 'hello',
76+
'count' => 2,
77+
]);
78+
79+
config([
80+
'workflows.serializer' => Y::class,
81+
]);
82+
83+
$this->assertSame([
84+
'message' => 'hello',
85+
'count' => 2,
86+
], Serializer::unserialize($serialized));
87+
}
88+
89+
public function testLegacyYPayloadStillWinsOverAvroDefault(): void
90+
{
91+
config([
92+
'workflows.serializer' => Y::class,
93+
]);
94+
95+
$serialized = Serializer::serialize([
96+
'legacy' => true,
97+
]);
98+
99+
config([
100+
'workflows.serializer' => 'avro',
101+
]);
102+
103+
$this->assertSame([
104+
'legacy' => true,
105+
], Serializer::unserialize($serialized));
106+
}
107+
68108
private function testSerializeUnserialize($data, $serializer, $unserializer): void
69109
{
70110
config([

0 commit comments

Comments
 (0)