Commit 9bced477 authored by Daniel Martí's avatar Daniel Martí

reflect: don't panic in ArrayOf if elem size is 0

We do a division by the elem type size to check if the array size would
be too large for the virtual address space. This is a silly check if the
size is 0, but the problem is that it means a division by zero and a
panic.

Since arrays of empty structs are valid in a regular program, make them
also work in reflect.

Use a separate, explicit test with struct{}{} to make sure the test for
a zero-sized type is not confused with the rest.

Fixes #20313.

Change-Id: I47b8b87e6541631280b79227bdea6a0f6035c9e0
Reviewed-on: https://go-review.googlesource.com/43131
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8304d107
......@@ -6016,6 +6016,7 @@ func TestTypeStrings(t *testing.T) {
{ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
{MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
{ArrayOf(3, TypeOf(XM{})), "[3]reflect_test.XM"},
{ArrayOf(3, TypeOf(struct{}{})), "[3]struct {}"},
}
for i, test := range stringTests {
......
......@@ -2814,9 +2814,11 @@ func ArrayOf(count int, elem Type) Type {
array.hash = fnv1(array.hash, ']')
array.elem = typ
array.ptrToThis = 0
max := ^uintptr(0) / typ.size
if uintptr(count) > max {
panic("reflect.ArrayOf: array size would exceed virtual address space")
if typ.size > 0 {
max := ^uintptr(0) / typ.size
if uintptr(count) > max {
panic("reflect.ArrayOf: array size would exceed virtual address space")
}
}
array.size = typ.size * uintptr(count)
if count > 0 && typ.ptrdata != 0 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment