• Joe Tsai's avatar
    encoding/json: avoid assuming side-effect free reflect.Value.Addr().Elem() · 4338518d
    Joe Tsai authored
    Consider the following:
    	type child struct{ Field string }
    	type parent struct{ child }
    
    	p := new(parent)
    	v := reflect.ValueOf(p).Elem().Field(0)
    	v.Field(0).SetString("hello")           // v.Field = "hello"
    	v = v.Addr().Elem()                     // v = *(&v)
    	v.Field(0).SetString("goodbye")         // v.Field = "goodbye"
    
    It would appear that v.Addr().Elem() should have the same value, and
    that it would be safe to set "goodbye".
    However, after CL 66331, any interspersed calls between Field calls
    causes the RO flag to be set.
    Thus, setting to "goodbye" actually causes a panic.
    
    That CL affects decodeState.indirect which assumes that back-to-back
    Value.Addr().Elem() is side-effect free. We fix that logic to keep
    track of the Addr() and Elem() calls and set v back to the original
    after a full round-trip has occured.
    
    Fixes #24152
    Updates #24153
    
    Change-Id: Ie50f8fe963f00cef8515d89d1d5cbc43b76d9f9c
    Reviewed-on: https://go-review.googlesource.com/97796Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
    Run-TryBot: Matthew Dempsky <mdempsky@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    4338518d
decode_test.go 53.3 KB