From 7089ea4e475a11beaed6837027b7f5254449989f Mon Sep 17 00:00:00 2001 From: HÃ¥vard Haugen Date: Sun, 7 Jun 2015 21:28:58 +0200 Subject: testing/quick: probabilistically generate nil pointers The documentation for quick.Value says that it "returns an arbitrary value of the given type." In spite of this, nil values for pointers were never generated, which seems more like an oversight than an intentional choice. The lack of nil values meant that testing recursive type like type Node struct { Next *Node } with testing/quick would lead to a stack overflow since the data structure would never terminate. This change may break tests that don't check for nil with pointers returned from quick.Value. Two such instances were found in the standard library, one of which was in the testing/quick package itself. Fixes #8818. Change-Id: Id390dcce649d12fbbaa801ce6f58f5defed77e60 Reviewed-on: https://go-review.googlesource.com/10821 Reviewed-by: Adam Langley Run-TryBot: Adam Langley --- src/testing/quick/quick.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/testing/quick/quick.go') diff --git a/src/testing/quick/quick.go b/src/testing/quick/quick.go index 35b7b636b4..0e36810eb6 100644 --- a/src/testing/quick/quick.go +++ b/src/testing/quick/quick.go @@ -102,12 +102,16 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { v.SetMapIndex(key, value) } case reflect.Ptr: - elem, ok := Value(concrete.Elem(), rand) - if !ok { - return reflect.Value{}, false + if rand.Intn(complexSize) == 0 { + v.Set(reflect.Zero(concrete)) // Generate nil pointer. + } else { + elem, ok := Value(concrete.Elem(), rand) + if !ok { + return reflect.Value{}, false + } + v.Set(reflect.New(concrete.Elem())) + v.Elem().Set(elem) } - v.Set(reflect.New(concrete.Elem())) - v.Elem().Set(elem) case reflect.Slice: numElems := rand.Intn(complexSize) v.Set(reflect.MakeSlice(concrete, numElems, numElems)) -- cgit v1.3-5-g45d5