Skip to content

Commit 8d2b1cb

Browse files
committed
AVRO-4298: [php] Reject negative union branch index
schemaByIndex validated only the upper bound (count > index), so a negative index passed the check and then indexed $schemas[-1] => null, violating the AvroSchema return type with a TypeError instead of a clean AvroException. Add a lower-bound check (index >= 0) so a negative branch index is rejected with AvroSchemaParseException. Adds tests for negative and too-large union indices. (readEnum is already guarded via array_key_exists.) Assisted-by: GitHub Copilot:claude-opus-4.8
1 parent 0d02b5b commit 8d2b1cb

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

lang/php/lib/Schema/AvroUnionSchema.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public function schemas(): array
9898
*/
9999
public function schemaByIndex($index): AvroSchema
100100
{
101-
if (count($this->schemas) > $index) {
101+
if ($index >= 0 && count($this->schemas) > $index) {
102102
return $this->schemas[$index];
103103
}
104104

lang/php/test/DatumIOTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,24 @@ public function test_read_map_rejects_count_beyond_stream(): void
316316
$this->decodeWith('{"type":"map","values":"long"}', $io);
317317
}
318318

319+
public function test_read_union_rejects_out_of_range_index(): void
320+
{
321+
// Index 5 (zig-zag long) is out of range for a 2-branch union.
322+
$io = new AvroStringIO();
323+
(new AvroIOBinaryEncoder($io))->writeLong(5);
324+
$this->expectException(AvroException::class);
325+
$this->decodeWith('["null","long"]', $io);
326+
}
327+
328+
public function test_read_union_rejects_negative_index(): void
329+
{
330+
// A negative index must not wrap to a valid branch.
331+
$io = new AvroStringIO();
332+
(new AvroIOBinaryEncoder($io))->writeLong(-1);
333+
$this->expectException(AvroException::class);
334+
$this->decodeWith('["null","long"]', $io);
335+
}
336+
319337
public function test_read_array_of_null_not_falsely_rejected(): void
320338
{
321339
$count = 100000;

0 commit comments

Comments
 (0)