Skip to content

encoding/json: Unmarshal map[string]interface{} target mishandled when passed as an interface{} #33487

@jexh

Description

@jexh

What version of Go are you using (go version)?

$ go version
go version go1.12.6 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN="xxx"
GOCACHE="xxx"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="xxx"
GOPROXY=""
GORACE=""
GOROOT="xxx"
GOTMPDIR=""
GOTOOLDIR="xxx"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build894533395=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Used a reference to the same map in multiple call to json.Unmarshal. See https://play.golang.org/p/bum-Q01e96M

What did you expect to see?

Expected JSON unmarshaling into maps to merge entries between different calls to json.Unmarshal, as indicated by the docs.

The play example should output:

map1: map[key1:data1 key2:data2]
map2: map[key1:data1 key2:data2]
map3: map[key1:map[key1.1:data1 key1.2:data2]]

What did you see instead?

Whenever the type of the unmarshal target is interface{} then a replacement value is created even if the existing entry is of type map[string]interface{} and is a suitable instance for unmarshal to use.

The play example outputs:

result: map[key2:data2]
result: map[key1:data1 key2:data2]
result: map[key1:map[key1.2:data2]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions