Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: unmarshal accepts duplicate keys #24415

Closed
Dirbaio opened this issue Mar 15, 2018 · 3 comments

Comments

Projects
None yet
6 participants
@Dirbaio
Copy link

commented Mar 15, 2018

Unmarshaling a JSON object with repeated keys into a struct doesn't return an error, it keeps the value specified last in the JSON string instead.

https://play.golang.org/p/cv6HeD-hERx

More confusingly, it causes maps on repeated keys to be merged: https://play.golang.org/p/47_7kSPFCW2

Other languages' JSON libraries error in this case

@dsnet dsnet changed the title JSON unmarshal accepts duplicate keys encoding/json: unmarshal accepts duplicate keys Mar 15, 2018

@ALTree ALTree added this to the Go1.11 milestone Mar 15, 2018

@dpinela

This comment has been minimized.

Copy link
Contributor

commented Mar 15, 2018

The documentation doesn't specify what happens in this case; it says it matches object keys to fields but doesn't specify in what order it does so (it only matters with duplicate keys). Changing the current behaviour might break backwards compatibility too much, but I think at least it should be documented.

Also, the behaviour is inconsistent between a map and a slice field; the maps get merged, the slice field takes the last value seen, like the other types.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Mar 26, 2018

This is working exactly as documented (see 'go doc json.Unmarshal'). I'm sorry if it's surprising behavior, but we can't change it now.

@rsc rsc closed this Mar 26, 2018

@mvdan

This comment has been minimized.

Copy link
Member

commented Mar 27, 2018

@rsc thanks for the reply. You're right that the godoc says that keys are matched, so it is implicit that nothing is done about duplicate keys. However, I don't see how that should lead to maps getting merged.

That is, in @Dirbaio's second play link, I would expect the output to be {map[bar:1]}.

I understand that unmarshalling multiple times into one map merges the keys - that is fine. What I don't think is fine is for duplicate keys to get merged. For example, as @dpinela said, when the field is a slice they aren't merged and you get a single element: https://play.golang.org/p/nXLs0hd8Uj3

@golang golang locked and limited conversation to collaborators Mar 27, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.