]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: don't panic marshaling anonymous non-struct field
authorThomas Kappler <tkappler@gmail.com>
Wed, 2 Jan 2013 22:39:41 +0000 (17:39 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 2 Jan 2013 22:39:41 +0000 (17:39 -0500)
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

src/pkg/encoding/json/encode.go
src/pkg/encoding/json/encode_test.go

index c3018ad2932a671a8427d4e2677fa903f87d14d9..83d5ee88b83a6cb8bd2fe3edb173d237a0e85d4f 100644 (file)
@@ -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})
index cb1c77eb529f7ab112606f61eb638bd947f4c29e..be74c997cf82dda7f905e5606290b600d62aa905 100644 (file)
@@ -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)
+       }
+}