-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/gob: roundtrip fail for a struct embedding a field implementing Gob{Decoder,Encoder} #22172
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
Comments
Workaround for golang/go#22172. modified: ir.go modified: operation.go modified: value.go
This isn't a bug; |
As explained, it is working as intended. That's how embedded fields behave. |
FTR: I consider the "explanation" mostly irrelevant to the problem. It is clear how embedded fields work, but that just make us know why calling First of all, it's true that this is working as documented, because
However, I don't think the implementation is correct when seeing that U implements GobEncoder - but only through method promotion of T's method. The problem is that T's GobEncoder implementation has no way to know its receiver is embedded in another struct and access U's fields. This defeats the "complete control" quoted above. T has complete control of encoding U, when embedded in U, but in the same time no access to U's instance. This can lead to some scenarios, which I consider problematic. One of them is the code in this issue, some random other:
These are all risky situations, not only from the data loss point of view, but it can be also a security risk, when certain fields stay unexpectedly at zero values when decoded from a gob encoding vaues with knowingly non zero value fields. I think the proper handling should consider only types implementing GobEncode by themselves, not by promotion, because, let me repeat myself, in the case of using GobEncode promoted methods the type, in this case PS: I haven't checked, but I assume reflection can distinguish between promoted methods and methods implemented directly by a type. If that assumption is false then there's of course probably no way to change/fix this. I don't want to prolongue talking on a closed issue, but if this stays considered not a bug, I may submit a proposal to change gob's behavior, if someone thinks it should be done. |
Everything you describe is working as expected and documented. Yes, you should be careful about embedding types that implement a |
I see, thank you. WDYT about filling a documentation issue suggesting adding a reformulation of the above, something like
? It's not too hard to fall into this trap. The intent is to possibly save others the time I spent debugging when I run into this situation.
By possibility you mean to change the behavior? I then assume that reflection cannot distinguish between "own" and promoted methods. Is that correct? If so, then maybe a separate issue for adding such feature to the reflect package should be filled. Any opinion about this? |
Personally I think your doc suggestion adds too much text and in the wrong place. This kind of discussion seems more appropriate in a discussion of embedded types, as it is not specific to encoding/gob. For example, it comes up more often in the way that the fmt package handles the Yes, I meant that as far as I know the reflect package can not distinguish directly implemented methods and promoted methods. I don't think such a feature should be added. In general, the reflect package implements what the language implements, and in the language promoted methods are the same as methods defined directly on the type. |
I'll add that I'm sorry you got bitten so badly by this. It is a corner of the language that can catch people by surprise. But if better docs are needed, let's make sure to put them in the right place. |
Gob lesson learned and learning new things is always good, no problem here. Thank you for taking the time to reply. |
What version of Go are you using (
go version
)?go version go1.9.1 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?What did you do?
Playground
What did you expect to see?
Nothing
What did you see instead?
The text was updated successfully, but these errors were encountered: