From 5866a47e77e2cecb794267fe2e0505187b7a31ca Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 11 Nov 2021 22:22:28 +0100 Subject: [PATCH] reflect: fix Value.Index() in a specific case In the case where: - Value.Index() was called on an array - that array was bigger than a pointer - the element type fits in a pointer - the 'indirect' flag isn't set the Value.Index() method would still (incorrectly) load the value. This commit fixes that. The next commit adds a test which would have triggered this bug so works as a regression test. --- src/reflect/value.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/reflect/value.go b/src/reflect/value.go index fd19eff7..abc35fb8 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -528,11 +528,17 @@ func (v Value) Index(i int) Value { if size > unsafe.Sizeof(uintptr(0)) { // The element fits in a pointer, but the array does not. // Load the value from the pointer. - addr := uintptr(v.value) + elemSize*uintptr(i) // pointer to new value + addr := unsafe.Pointer(uintptr(v.value) + elemSize*uintptr(i)) // pointer to new value + value := addr + if !v.isIndirect() { + // Use a pointer to the value (don't load the value) if the + // 'indirect' flag is set. + value = unsafe.Pointer(loadValue(addr, elemSize)) + } return Value{ typecode: v.typecode.elem(), flags: v.flags, - value: unsafe.Pointer(loadValue(unsafe.Pointer(addr), elemSize)), + value: value, } }