]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: fix scanner byte offset on scanEnd
authoritchyny <itchyny@hatena.ne.jp>
Mon, 2 Sep 2019 00:07:40 +0000 (00:07 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Mon, 2 Sep 2019 11:00:29 +0000 (11:00 +0000)
scanEnd is delayed one byte so we decrement
the scanner bytes count by 1 to ensure that
this value is correct in the next call of Decode.

Fixes #32399

Change-Id: I8c8698e7f95bbcf0373aceaa05319819eae9d86f
GitHub-Last-Rev: 0ac25d8de23d38c7ac577faddc6983571023f561
GitHub-Pull-Request: golang/go#32598
Reviewed-on: https://go-review.googlesource.com/c/go/+/182117
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/encoding/json/decode_test.go
src/encoding/json/stream.go

index 8dcb08cbd27762a39efa5d7a3336c8368484e6ea..31ab61c7335e1e7cf4336a33fe0f2955891669a4 100644 (file)
@@ -2345,6 +2345,41 @@ func TestUnmarshalEmbeddedUnexported(t *testing.T) {
        }
 }
 
+func TestUnmarshalErrorAfterMultipleJSON(t *testing.T) {
+       tests := []struct {
+               in  string
+               err error
+       }{{
+               in:  `1 false null :`,
+               err: &SyntaxError{"invalid character ':' looking for beginning of value", 14},
+       }, {
+               in:  `1 [] [,]`,
+               err: &SyntaxError{"invalid character ',' looking for beginning of value", 7},
+       }, {
+               in:  `1 [] [true:]`,
+               err: &SyntaxError{"invalid character ':' after array element", 11},
+       }, {
+               in:  `1  {}    {"x"=}`,
+               err: &SyntaxError{"invalid character '=' after object key", 14},
+       }, {
+               in:  `falsetruenul#`,
+               err: &SyntaxError{"invalid character '#' in literal null (expecting 'l')", 13},
+       }}
+       for i, tt := range tests {
+               dec := NewDecoder(strings.NewReader(tt.in))
+               var err error
+               for {
+                       var v interface{}
+                       if err = dec.Decode(&v); err != nil {
+                               break
+                       }
+               }
+               if !reflect.DeepEqual(err, tt.err) {
+                       t.Errorf("#%d: got %#v, want %#v", i, err, tt.err)
+               }
+       }
+}
+
 type unmarshalPanic struct{}
 
 func (unmarshalPanic) UnmarshalJSON([]byte) error { panic(0xdead) }
index e29127499b638a1328cae467ccac866ec618088f..3d30322ce2597a6158325963679759f739c8663a 100644 (file)
@@ -102,6 +102,10 @@ Input:
                        dec.scan.bytes++
                        switch dec.scan.step(&dec.scan, c) {
                        case scanEnd:
+                               // scanEnd is delayed one byte so we decrement
+                               // the scanner bytes count by 1 to ensure that
+                               // this value is correct in the next call of Decode.
+                               dec.scan.bytes--
                                break Input
                        case scanEndObject, scanEndArray:
                                // scanEnd is delayed one byte.