mirror of
https://github.com/golang/go.git
synced 2025-05-31 23:25:39 +00:00
encoding/json: don't panic marshaling anonymous non-struct field
Add a check for this case and don't try to follow the anonymous type's non-existent fields. Fixes #4474. R=rsc CC=golang-dev https://golang.org/cl/6945065
This commit is contained in:
parent
a29702f067
commit
cdec0850f8
@ -617,13 +617,20 @@ func typeFields(t reflect.Type) []field {
|
||||
index := make([]int, len(f.index)+1)
|
||||
copy(index, f.index)
|
||||
index[len(f.index)] = i
|
||||
|
||||
ft := sf.Type
|
||||
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
|
||||
// Follow pointer.
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
// Record found field and index sequence.
|
||||
if name != "" || !sf.Anonymous {
|
||||
if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||
tagged := name != ""
|
||||
if name == "" {
|
||||
name = sf.Name
|
||||
}
|
||||
fields = append(fields, field{name, tagged, index, sf.Type,
|
||||
fields = append(fields, field{name, tagged, index, ft,
|
||||
opts.Contains("omitempty"), opts.Contains("string")})
|
||||
if count[f.typ] > 1 {
|
||||
// If there were multiple instances, add a second,
|
||||
@ -636,11 +643,6 @@ func typeFields(t reflect.Type) []field {
|
||||
}
|
||||
|
||||
// Record new anonymous struct to explore in next round.
|
||||
ft := sf.Type
|
||||
if ft.Name() == "" {
|
||||
// Must be pointer.
|
||||
ft = ft.Elem()
|
||||
}
|
||||
nextCount[ft]++
|
||||
if nextCount[ft] == 1 {
|
||||
next = append(next, field{name: ft.Name(), index: index, typ: ft})
|
||||
|
@ -186,3 +186,23 @@ func TestMarshalerEscaping(t *testing.T) {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type IntType int
|
||||
|
||||
type MyStruct struct {
|
||||
IntType
|
||||
}
|
||||
|
||||
func TestAnonymousNonstruct(t *testing.T) {
|
||||
var i IntType = 11
|
||||
a := MyStruct{i}
|
||||
const want = `{"IntType":11}`
|
||||
|
||||
b, err := Marshal(a)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if got := string(b); got != want {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user