]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: don't panic in ArrayOf if elem size is 0
authorDaniel Martí <mvdan@mvdan.cc>
Wed, 10 May 2017 11:53:39 +0000 (13:53 +0200)
committerDaniel Martí <mvdan@mvdan.cc>
Wed, 10 May 2017 13:44:53 +0000 (13:44 +0000)
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>
src/reflect/all_test.go
src/reflect/type.go

index b3b82f8b2ae28b291b4b76ce693a07a410cefc25..4953e4ff83b2a394fb31a4c3a6c4332a2a9f1fb2 100644 (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 {
index 637392f4e7688ebbc273726a806b8f4e477d7d79..1849c4b8d407a4c63054dd4ba3dedc6822986f4c 100644 (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 {