1
0
mirror of https://github.com/golang/go synced 2024-11-18 11:44:45 -07:00

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: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Daniel Martí 2017-05-10 13:53:39 +02:00
parent 8304d10763
commit 9bced47706
2 changed files with 6 additions and 3 deletions

View File

@ -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 {

View File

@ -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 {