]> Cypherpunks repositories - gostls13.git/commit
encoding/json: reuse values when decoding map elements
authorDaniel Martí <mvdan@mvdan.cc>
Wed, 29 May 2019 10:09:50 +0000 (11:09 +0100)
committerDaniel Martí <mvdan@mvdan.cc>
Fri, 8 May 2020 21:19:55 +0000 (21:19 +0000)
commit60368c2477d2517d7d4d83412eba5420fdb81a2b
treea751bef93b67c12c38db07a92b4e19f3b9d4abf4
parentf1ac85c8d10e16fbc07e8b7ef93aa04bdc4c67e9
encoding/json: reuse values when decoding map elements

When we decode into a struct, each input key-value may be decoded into
one of the struct's fields. Particularly, existing data isn't dropped,
so that some sub-fields can be decoded into without zeroing all other
data.

However, decoding into a map behaved in the opposite way. Whenever a
key-value was decoded, it completely replaced the previous map element.
If the map contained any non-zero data in that key, it's dropped.

Instead, try to reuse the existing element value if possible. If the map
element type is a pointer, and the value is non-nil, we can decode
directly into it. If it's not a pointer, make a copy and decode into
that copy, as map element values aren't addressable.

This means we have to parse and convert the map element key before the
value, to be able to obtain the existing element value. This is fine,
though. Moreover, reporting errors on the key before the value follows
the input order more closely.

Finally, add a test to explore the four combinations, involving pointer
and non-pointer, and non-zero and zero values. A table-driven test
wasn't used, as each case required different checks, such as checking
that the non-nil pointer case doesn't end up with a different pointer.

Fixes #31924.

Change-Id: I5ca40c9963a98aaf92f26f0b35843c021028dfca
Reviewed-on: https://go-review.googlesource.com/c/go/+/179337
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/encoding/json/decode.go
src/encoding/json/decode_test.go