From: Russ Cox Date: Wed, 12 Oct 2016 19:55:02 +0000 (-0400) Subject: encoding/json: handle misspelled JSON literals in ,string X-Git-Tag: go1.8beta1~884 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0da30d5cbdd092499fe199c212f8799fd0cc676e;p=gostls13.git encoding/json: handle misspelled JSON literals in ,string Fixes #15146. Change-Id: I229611b9cc995a1391681c492c4d742195c787ea Reviewed-on: https://go-review.googlesource.com/30943 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index ceaecec67c..ee3585f3e6 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -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 { diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index 37dbfeb5f3..b1c4658e1b 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -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) {