Pārlūkot izejas kodu

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.
Dave Collins 11 gadi atpakaļ
vecāks
revīzija
83f84dc933
1 mainītis faili ar 13 papildinājumiem un 1 dzēšanām
  1. 13 1
      spew/common.go

+ 13 - 1
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)