-
Notifications
You must be signed in to change notification settings - Fork 18k
net: IPNet JSON marshal/unmarshal inconsistency #35727
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
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Comments
/cc @mvdan |
Also /cc @mikioh |
Another way to reproduce the problem, without Playground: https://play.golang.org/p/VgWt3PtRN8o |
Yep, got hit by that as well, had to implement custom marshal and a wrapper struct as marshal/unmarshal doesn't really work. |
yevgenypats
added a commit
to cloudquery/plugin-sdk
that referenced
this issue
Nov 15, 2022
yevgenypats
added a commit
to cloudquery/plugin-sdk
that referenced
this issue
Nov 15, 2022
yevgenypats
added a commit
to cloudquery/plugin-sdk
that referenced
this issue
Nov 15, 2022
yevgenypats
added a commit
to cloudquery/plugin-sdk
that referenced
this issue
Nov 15, 2022
kodiakhq bot
pushed a commit
to cloudquery/plugin-sdk
that referenced
this issue
Nov 15, 2022
Fix nasty bug triggered by Go bug golang/go#35727 @shimonp21 can you please confirm this solves the bug triggered by the k8s cidr plugin.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Wrote code that uses
net.ParseCIDR()
to create a*net.IPNet
, then usesjson.Marshal()
to serialize it to JSON, then usesjson.Unmarshal()
to deserialize it back to*net.IPNet
.Here's a link: https://play.golang.org/p/ryc7rp4KyiZ
Code just in case:
What did you expect to see?
I expected that the original and deserialized values will be equal.
What did you see instead?
I saw that the original and deserialized values are different.
Specifically, I saw that the original value as returned from
net.ParseCIDR()
uses 4-byte representation and the value as deserialized byjson.Unmarshal()
uses 16-byte representation. The values might be semantically equivalent but the internal byte representation is different. Note that this value (net.IPNet.IP
) is managed internally and not used at all by the calling code.I think this might be because
net.ParseCIDR()
masks thenet.IPNet.IP
field with a mask that is limited by the IP address length and by default assumes IPv4, so 4-byte representation. The result is that for an IPv4 CIDR, the internalnet.IPNet.IP
will always be in 4-byte representation. TheIP.UnmarshalText()
function usesnet.ParseIP()
, though, which callsparseIPv4()
, which in turn usesnet.IPv4()
to construct thenet.IP
that is returned. Butnet.IPv4()
uses 16-byte representation ("v4-in-v6 prefix").I think this is not ideal since in order to get semantics where input is equal to output one has to add code as below, which alters internal data structures:
If this is indeed considered a problem, a naive suggestion would be to add an unmarshal function for
net.IPNet
that usesnet.ParseCIDR()
and thus retaining semantics. I don't know if that's viable though or what unforeseen effects this might have.The text was updated successfully, but these errors were encountered: