From 06a6b0bda8ad73902832d77e61214918aee65453 Mon Sep 17 00:00:00 2001 From: Herbie Ong Date: Wed, 24 Apr 2019 21:15:45 -0700 Subject: [PATCH] encoding/jsonpb: fix parsing of number strings containing leading/trailing spaces Per conformance tests, number strings that contain leading or trailing spaces are not allowed. https://github.com/protocolbuffers/protobuf/blob/3a3956e8a258784461270961c6577341356bce52/conformance/binary_json_conformance_suite.cc#L1196-L1203 Change-Id: Ifbe0e4ee125fac3c291b456eece541353025cdd4 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/173664 Reviewed-by: Joe Tsai --- encoding/jsonpb/decode.go | 15 +++++++++++++-- encoding/jsonpb/decode_test.go | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/encoding/jsonpb/decode.go b/encoding/jsonpb/decode.go index 4b46ffc2..4b0d9bbb 100644 --- a/encoding/jsonpb/decode.go +++ b/encoding/jsonpb/decode.go @@ -376,7 +376,11 @@ func unmarshalInt(jval json.Value, bitSize int) (pref.Value, error) { case json.String: // Decode number from string. - dec := json.NewDecoder([]byte(jval.String())) + s := strings.TrimSpace(jval.String()) + if len(s) != len(jval.String()) { + return pref.Value{}, errors.New("invalid number %v", jval.Raw()) + } + dec := json.NewDecoder([]byte(s)) var nerr errors.NonFatal jval, err := dec.Read() if !nerr.Merge(err) { @@ -405,7 +409,11 @@ func unmarshalUint(jval json.Value, bitSize int) (pref.Value, error) { case json.String: // Decode number from string. - dec := json.NewDecoder([]byte(jval.String())) + s := strings.TrimSpace(jval.String()) + if len(s) != len(jval.String()) { + return pref.Value{}, errors.New("invalid number %v", jval.Raw()) + } + dec := json.NewDecoder([]byte(s)) var nerr errors.NonFatal jval, err := dec.Read() if !nerr.Merge(err) { @@ -452,6 +460,9 @@ func unmarshalFloat(jval json.Value, bitSize int) (pref.Value, error) { return pref.ValueOf(math.Inf(-1)), nil } // Decode number from string. + if len(s) != len(strings.TrimSpace(s)) { + return pref.Value{}, errors.New("invalid number %v", jval.Raw()) + } dec := json.NewDecoder([]byte(s)) var nerr errors.NonFatal jval, err := dec.Read() diff --git a/encoding/jsonpb/decode_test.go b/encoding/jsonpb/decode_test.go index 9fb95d6d..6226b07e 100644 --- a/encoding/jsonpb/decode_test.go +++ b/encoding/jsonpb/decode_test.go @@ -252,6 +252,16 @@ func TestUnmarshal(t *testing.T) { SFloat: float32(math.Inf(+1)), SDouble: math.Inf(-1), }, + }, { + desc: "float string with leading space", + inputMessage: &pb3.Scalars{}, + inputText: `{"sFloat": " 1.234"}`, + wantErr: true, + }, { + desc: "double string with trailing space", + inputMessage: &pb3.Scalars{}, + inputText: `{"sDouble": "5.678 "}`, + wantErr: true, }, { desc: "not float", inputMessage: &pb3.Scalars{}, @@ -323,6 +333,16 @@ func TestUnmarshal(t *testing.T) { wantMessage: &pb3.Scalars{ SInt32: 12, }, + }, { + desc: "integer string with leading space", + inputMessage: &pb3.Scalars{}, + inputText: `{"sInt32": " 1234"}`, + wantErr: true, + }, { + desc: "integer string with trailing space", + inputMessage: &pb3.Scalars{}, + inputText: `{"sUint32": "1e2 "}`, + wantErr: true, }, { desc: "number is not an integer", inputMessage: &pb3.Scalars{},