-
Notifications
You must be signed in to change notification settings - Fork 13
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
Fix hash calculation based on proto.Struct #1318
Conversation
0919511
to
c47da2f
Compare
Co-Authored-By: Nicolas Mahé <nicolas@mesg.com>
// NOTE: structhash will allow to process all interface types. | ||
// gogo/protobuf is not able to set tags for directly oneof interface. | ||
// see: https://github.com/gogo/protobuf/issues/623 | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another problem, the following is returning {a:{b:1}}
:
{ | |
{ | |
struct { | |
a interface{} | |
}{ | |
struct { | |
b interface{} | |
}{ | |
b: 1, | |
}, | |
}, | |
"{a:{}}", | |
}, | |
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solution, replace in structhash.go line 105 by:
- if to.name == "" && reflect.Zero(sf.Type).Kind() == reflect.Interface {
+ if to.name == "" && v.Field(i).Kind() == reflect.Interface && v.Field(i).Elem().Kind() == reflect.Struct {
It will only continue if the field is defined as type interface and has as "real" type Struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how it interface works. It's not a bug, it done design.
So let's break it down:
a struct
is passed with a interface{]
fileds which has no tag.
A struct is serialized and a
field is serialized because it's an interface.
Then interface{}
has struct inside. That struct is serialized because it's not a field of any struct, but rather the object (interface value). The struct contains b
fields which is an interface so it's serialized and interface value contains an integer. So the final output should be {a:{b:1}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test line 60 is wrong:
{
struct {
a int `hash:"omitempty"`
}{1},
"{}",
},
it should returns {a:1}
Solution:
Replace hash:"omitempty"
by hash:"name:a,omitempty"
So any field without an explicit hash name is discarded?
It's not. Field |
close #1315