Commit cdec0850 authored by Thomas Kappler's avatar Thomas Kappler Committed by Russ Cox

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
parent a29702f0
...@@ -617,13 +617,20 @@ func typeFields(t reflect.Type) []field { ...@@ -617,13 +617,20 @@ func typeFields(t reflect.Type) []field {
index := make([]int, len(f.index)+1) index := make([]int, len(f.index)+1)
copy(index, f.index) copy(index, f.index)
index[len(f.index)] = i 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. // Record found field and index sequence.
if name != "" || !sf.Anonymous { if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
tagged := name != "" tagged := name != ""
if name == "" { if name == "" {
name = sf.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")}) opts.Contains("omitempty"), opts.Contains("string")})
if count[f.typ] > 1 { if count[f.typ] > 1 {
// If there were multiple instances, add a second, // If there were multiple instances, add a second,
...@@ -636,11 +643,6 @@ func typeFields(t reflect.Type) []field { ...@@ -636,11 +643,6 @@ func typeFields(t reflect.Type) []field {
} }
// Record new anonymous struct to explore in next round. // Record new anonymous struct to explore in next round.
ft := sf.Type
if ft.Name() == "" {
// Must be pointer.
ft = ft.Elem()
}
nextCount[ft]++ nextCount[ft]++
if nextCount[ft] == 1 { if nextCount[ft] == 1 {
next = append(next, field{name: ft.Name(), index: index, typ: ft}) next = append(next, field{name: ft.Name(), index: index, typ: ft})
......
...@@ -186,3 +186,23 @@ func TestMarshalerEscaping(t *testing.T) { ...@@ -186,3 +186,23 @@ func TestMarshalerEscaping(t *testing.T) {
t.Errorf("got %q, want %q", got, want) 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)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment