Skip to content

Commit c021244

Browse files
authored
Merge pull request #182 from ialidzhikov/cherrypick/panic-on-embedded-struct
Cherry pick of #173: Fix panic on pointer to embedded struct
2 parents d8c62e5 + dce0ab5 commit c021244

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

value/reflectcache.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ func (f *FieldCacheEntry) CanOmit(fieldVal reflect.Value) bool {
7070
return f.isOmitEmpty && (safeIsNil(fieldVal) || isZero(fieldVal))
7171
}
7272

73-
// GetUsing returns the field identified by this FieldCacheEntry from the provided struct.
73+
// GetFrom returns the field identified by this FieldCacheEntry from the provided struct.
7474
func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value {
7575
// field might be nested within 'inline' structs
7676
for _, elem := range f.fieldPath {
77-
structVal = structVal.FieldByIndex(elem)
77+
structVal = dereference(structVal).FieldByIndex(elem)
7878
}
7979
return structVal
8080
}
@@ -150,7 +150,11 @@ func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fi
150150
continue
151151
}
152152
if isInline {
153-
buildStructCacheEntry(field.Type, infos, append(fieldPath, field.Index))
153+
e := field.Type
154+
if field.Type.Kind() == reflect.Ptr {
155+
e = field.Type.Elem()
156+
}
157+
buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
154158
continue
155159
}
156160
info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}

value/valuereflect_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ type testOmitemptyStruct struct {
237237
Noomit *string `json:"noomit"`
238238
Omit *string `json:"omit,omitempty"`
239239
}
240+
type testEmbeddedStruct struct {
241+
*testBasicStruct `json:",inline"`
242+
}
240243

241244
func TestReflectStruct(t *testing.T) {
242245
cases := []struct {
@@ -281,6 +284,12 @@ func TestReflectStruct(t *testing.T) {
281284
expectedMap: map[string]interface{}{"noomit": (*string)(nil)},
282285
expectedUnstructured: map[string]interface{}{"noomit": nil},
283286
},
287+
{
288+
name: "embedded",
289+
val: testEmbeddedStruct{&testBasicStruct{I: 10, S: "string"}},
290+
expectedMap: map[string]interface{}{"int": int64(10), "S": "string"},
291+
expectedUnstructured: map[string]interface{}{"int": int64(10), "S": "string"},
292+
},
284293
}
285294

286295
for _, tc := range cases {

0 commit comments

Comments
 (0)