]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: handle misspelled JSON literals in ,string
authorRuss Cox <rsc@golang.org>
Wed, 12 Oct 2016 19:55:02 +0000 (15:55 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 13 Oct 2016 17:30:39 +0000 (17:30 +0000)
Fixes #15146.

Change-Id: I229611b9cc995a1391681c492c4d742195c787ea
Reviewed-on: https://go-review.googlesource.com/30943
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/encoding/json/decode.go
src/encoding/json/decode_test.go

index ceaecec67cf6e5d15e385853a23f5b01d1fb8256..ee3585f3e614985d909f3594d5cb823333524be9 100644 (file)
@@ -851,13 +851,25 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
 
        switch c := item[0]; c {
        case 'n': // null
+               // The main parser checks that only true and false can reach here,
+               // but if this was a quoted string input, it could be anything.
+               if fromQuoted && string(item) != "null" {
+                       d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+                       break
+               }
                switch v.Kind() {
                case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
                        v.Set(reflect.Zero(v.Type()))
                        // otherwise, ignore null for primitives/string
                }
        case 't', 'f': // true, false
-               value := c == 't'
+               value := item[0] == 't'
+               // The main parser checks that only true and false can reach here,
+               // but if this was a quoted string input, it could be anything.
+               if fromQuoted && string(item) != "true" && string(item) != "false" {
+                       d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+                       break
+               }
                switch v.Kind() {
                default:
                        if fromQuoted {
index 37dbfeb5f3dc5e8e67a99503a7b7c9e3a95c513b..b1c4658e1b0cea42f348e354e9bf3163556fb68e 100644 (file)
@@ -379,6 +379,10 @@ type unmarshalTest struct {
        golden    bool
 }
 
+type B struct {
+       B bool `json:",string"`
+}
+
 var unmarshalTests = []unmarshalTest{
        // basic types
        {in: `true`, ptr: new(bool), out: true},
@@ -778,6 +782,16 @@ var unmarshalTests = []unmarshalTest{
                        Offset: 30,
                },
        },
+
+       // issue 15146.
+       // invalid inputs in wrongStringTests below.
+       {in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true},
+       {in: `{"B":"false"}`, ptr: new(B), out: B{false}, golden: true},
+       {in: `{"B": "maybe"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "maybe" into bool`)},
+       {in: `{"B": "tru"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "tru" into bool`)},
+       {in: `{"B": "False"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "False" into bool`)},
+       {in: `{"B": "null"}`, ptr: new(B), out: B{false}},
+       {in: `{"B": "nul"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "nul" into bool`)},
 }
 
 func TestMarshal(t *testing.T) {