]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: disable anonymous fields
authorRuss Cox <rsc@golang.org>
Sun, 19 Feb 2012 05:27:05 +0000 (00:27 -0500)
committerRuss Cox <rsc@golang.org>
Sun, 19 Feb 2012 05:27:05 +0000 (00:27 -0500)
We should, after Go 1, make them work the same as
package xml, that is, make them appear in the outer
struct.  For now turn them off so that people do not
depend on the old behavior.

Fixing them is issue 3069.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5656102

src/pkg/encoding/json/decode.go
src/pkg/encoding/json/decode_test.go
src/pkg/encoding/json/encode.go

index 87076b53dc06578d4b21b24293a957f1eb8d9566..110c6fd62386e5af5ad5871c9b31067c4175c569 100644 (file)
@@ -496,6 +496,12 @@ func (d *decodeState) object(v reflect.Value) {
                                        // Pretend this field doesn't exist.
                                        continue
                                }
+                               if sf.Anonymous {
+                                       // Pretend this field doesn't exist,
+                                       // so that we can do a good job with
+                                       // these in a later version.
+                                       continue
+                               }
                                // First, tag match
                                tagName, _ := parseTag(tag)
                                if tagName == key {
@@ -963,3 +969,11 @@ func unquoteBytes(s []byte) (t []byte, ok bool) {
        }
        return b[0:w], true
 }
+
+// The following is issue 3069.
+
+// BUG(rsc): This package ignores anonymous (embedded) struct fields
+// during encoding and decoding.  A future version may assign meaning
+// to them.  To force an anonymous field to be ignored in all future
+// versions of this package, use an explicit `json:"-"` tag in the struct
+// definition.
index 775becfa7c9be2699e127a088f1cc3f5feeaefa6..0eec586a9bb73eee8fbe37ccb5d7529fc3116a75 100644 (file)
@@ -619,3 +619,32 @@ func TestRefUnmarshal(t *testing.T) {
                t.Errorf("got %+v, want %+v", got, want)
        }
 }
+
+// Test that anonymous fields are ignored.
+// We may assign meaning to them later.
+func TestAnonymous(t *testing.T) {
+       type S struct {
+               T
+               N int
+       }
+
+       data, err := Marshal(new(S))
+       if err != nil {
+               t.Fatalf("Marshal: %v", err)
+       }
+       want := `{"N":0}`
+       if string(data) != want {
+               t.Fatalf("Marshal = %#q, want %#q", string(data), want)
+       }
+
+       var s S
+       if err := Unmarshal([]byte(`{"T": 1, "T": {"Y": 1}, "N": 2}`), &s); err != nil {
+               t.Fatalf("Unmarshal: %v", err)
+       }
+       if s.N != 2 {
+               t.Fatal("Unmarshal: did not set N")
+       }
+       if s.T.Y != 0 {
+               t.Fatal("Unmarshal: did set T.Y")
+       }
+}
index 83e73c09cb41c8d3bb80b5dae92e5c29a6487cb4..8a794b79bd5bb5c659466c70b75cf4886063351c 100644 (file)
@@ -538,6 +538,11 @@ func encodeFields(t reflect.Type) []encodeField {
                if f.PkgPath != "" {
                        continue
                }
+               if f.Anonymous {
+                       // We want to do a better job with these later,
+                       // so for now pretend they don't exist.
+                       continue
+               }
                var ef encodeField
                ef.i = i
                ef.tag = f.Name