From 83f84dc933714d51504ceed59f43ead21d096fe7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 15 Nov 2014 19:57:16 -0600 Subject: [PATCH] Improve unsafe reflect value handling. This commit modifies the unsafeReflectValue function to recognize reference types even when the indirection flag is not set for the series of golang commits after ecccf07e7f9d and before 82f48826c6c7 which introduced the additional scalar field in the reflect.Value struct. That additional field has since been removed, but the intention of this code is to work properly across all Go versions and other packages make use of the logic. Thanks to @shurcooL for providing example code which wasn't working properly with the function when it was exported and therefore being called in ways which spew itself does not. --- spew/common.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/spew/common.go b/spew/common.go index 2cec098..0ce0df1 100644 --- a/spew/common.go +++ b/spew/common.go @@ -109,7 +109,19 @@ func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { vt = reflect.PtrTo(v.Type()) indirects++ } else if offsetScalar != 0 { - upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetScalar) + // The value is in the scalar field when it's not one of the + // reference types. + switch vt.Kind() { + case reflect.Uintptr: + case reflect.Chan: + case reflect.Func: + case reflect.Map: + case reflect.Ptr: + case reflect.UnsafePointer: + default: + upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + + offsetScalar) + } } pv := reflect.NewAt(vt, upv)