]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: use reflect.Value.UnsafePointer over Pointer
authorJoe Tsai <joetsai@digital-static.net>
Tue, 2 Nov 2021 19:01:24 +0000 (12:01 -0700)
committerJoseph Tsai <joetsai@digital-static.net>
Wed, 2 Mar 2022 17:42:53 +0000 (17:42 +0000)
The latter returns a uintptr, while the former returns a unsafe.Pointer.
A uintptr is unsafe if Go ever switches to a moving GC,
while a unsafe.Pointer will be properly tracked by the GC.

We do not use unsafe.Pointer for any unsafe type conversions,
and only use it for comparability purposes, which is relatively safe.

Updates #40592

Change-Id: I813e218668704b63a3043acda4331205a3835a66
Reviewed-on: https://go-review.googlesource.com/c/go/+/360855
Trust: Joseph Tsai <joetsai@digital-static.net>
Trust: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/encoding/json/encode.go

index 1f5e3e446a9c9c2d92f21edfd5e84f2cea8e88fb..571ac094e2c477e7d57f2fb431b297ddb6a634c0 100644 (file)
@@ -784,7 +784,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
        if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
                // We're a large number of nested ptrEncoder.encode calls deep;
                // start checking if we've run into a pointer cycle.
-               ptr := v.Pointer()
+               ptr := v.UnsafePointer()
                if _, ok := e.ptrSeen[ptr]; ok {
                        e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
                }
@@ -877,9 +877,9 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
                // Here we use a struct to memorize the pointer to the first element of the slice
                // and its length.
                ptr := struct {
-                       ptr uintptr
+                       ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
                        len int
-               }{v.Pointer(), v.Len()}
+               }{v.UnsafePointer(), v.Len()}
                if _, ok := e.ptrSeen[ptr]; ok {
                        e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
                }