You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match.
i would expect the json key that exactly matches the tag (fieldSETid) to be unmarshalled to the struct (in this case, it should be "sdkgjfhdfsgj") in any json key ordering.
What did you see instead?
the last case-insensitive match encountered in the json object is the accepted value. this is what differs this from this issue: #11673
this would be completely acceptable if it was deterministic every time. however, json keys are not deterministic (in fact, my understanding is that golang's own marshal does not guarantee key order). this can lead to non-deterministic differences in unmarshal behavior, and there's not really a workaround other than changing the incoming payload (which may not be possible due to the fact that it may be generated using a system that does not have deterministic key order).
The text was updated successfully, but these errors were encountered:
dmitshur
changed the title
encoding/jsonunmarshal case insensitive match can lead to nondeterministic behavior
encoding/json: Unmarshal case insensitive match can lead to nondeterministic behavior
Jan 31, 2020
I think this is a duplicate of #14750; in particular, see my proposed solution at #14750 (comment). That would essentially be amending the docs to reflect the behavior we have had for years.
The alternative would be to change the implementation to reflect the documentation - that is, to give preference to the case sensitive match, no matter the order. However, I worry that that could easily break existing programs in subtle ways.
In any case, I think the discussion should continue in that previous issue.
yeah, i agree that the godoc is inconsistent, but i think this is a bug regardless of what the docs say. imo, the correct bug fix is not changing the docs, it's to change the behavior. i don't think it was ever the intention to cause non-deterministic behavior. in certain scenarios, safely unmarshalling the correct key is not supported, barring writing a custom unmarshaller. if there was a flag or something that you could specify to force the match to be case sensitive, then this would be fine. but as long as order determines which key gets unmarshalled, this is going to be an unsafe and unpredictable operation. i'm fine with moving the discussion over to that issue though. thanks for pointing that out to me.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
not sure. i was able to reproduce on my mac (1.13.3), as well as the playground.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://play.golang.org/p/6lgm5E0R0Nz
essentially, test the behavior of
unmarshal
with case-sensitive keys.What did you expect to see?
according to the wording in the godoc (https://godoc.org/encoding/json#Unmarshal):
i would expect the json key that exactly matches the tag (
fieldSETid
) to be unmarshalled to the struct (in this case, it should be"sdkgjfhdfsgj"
) in any json key ordering.What did you see instead?
the last case-insensitive match encountered in the json object is the accepted value. this is what differs this from this issue: #11673
this would be completely acceptable if it was deterministic every time. however, json keys are not deterministic (in fact, my understanding is that golang's own
marshal
does not guarantee key order). this can lead to non-deterministic differences inunmarshal
behavior, and there's not really a workaround other than changing the incoming payload (which may not be possible due to the fact that it may be generated using a system that does not have deterministic key order).The text was updated successfully, but these errors were encountered: