diff --git a/codec_array.go b/codec_array.go index 658ae58..3dd82fe 100644 --- a/codec_array.go +++ b/codec_array.go @@ -39,6 +39,10 @@ type arrayDecoder struct { decoder ValDecoder } +// Max allocation size for an array due to the limit in number of bits in a heap address: +// https://github.com/golang/go/blob/7f76c00fc5678fa782708ba8fece63750cb89d03/src/runtime/malloc.go#L183 +var maxAllocSize = uint64(1 << 48) + func (d *arrayDecoder) Decode(ptr unsafe.Pointer, r *Reader) { var size int sliceType := d.typ @@ -51,6 +55,10 @@ func (d *arrayDecoder) Decode(ptr unsafe.Pointer, r *Reader) { start := size size += int(l) + if size > int(maxAllocSize) { + r.ReportError("decode array", "size exceeded max allocation size") + return + } sliceType.UnsafeGrow(ptr, size) for i := start; i < size; i++ { diff --git a/decoder_array_test.go b/decoder_array_test.go index 57107ba..f50ec3b 100644 --- a/decoder_array_test.go +++ b/decoder_array_test.go @@ -78,3 +78,16 @@ func TestDecoder_ArraySliceItemError(t *testing.T) { assert.Error(t, err) } + +func TestDecoder_ArrayMaxAllocationError(t *testing.T) { + defer ConfigTeardown() + data := []byte{0x2, 0x0, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0x0} + schema := `{"type":"array", "items": { "type": "boolean" }}` + dec, err := avro.NewDecoder(schema, bytes.NewReader(data)) + require.NoError(t, err) + + var got []bool + err = dec.Decode(&got) + + assert.Error(t, err) +}