mirror of
https://github.com/golang/go.git
synced 2025-12-28 06:34:04 +00:00
encoding/json: report true from v2 Decoder.More when an error is pending
Historically, Decoder.More reports true when the next read will return an error. Adjust the v2 Decoder to follow this behavior. Fixes #76467 Change-Id: I03bfa391e4e89ada8ca869db43c1d0bb63cc0413 Reviewed-on: https://go-review.googlesource.com/c/go/+/728300 Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Joseph Tsai <joetsai@digital-static.net> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
7b60d06739
commit
00642ee23b
@ -459,6 +459,9 @@ func TestDecodeInStream(t *testing.T) {
|
||||
{CaseName: Name(""), json: ` \a`, expTokens: []any{
|
||||
&SyntaxError{"invalid character '\\\\' looking for beginning of value", 1},
|
||||
}},
|
||||
{CaseName: Name(""), json: `,`, expTokens: []any{
|
||||
&SyntaxError{"invalid character ',' looking for beginning of value", 0},
|
||||
}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
@ -467,6 +470,15 @@ func TestDecodeInStream(t *testing.T) {
|
||||
var got any
|
||||
var err error
|
||||
|
||||
wantMore := true
|
||||
switch want {
|
||||
case Delim(']'), Delim('}'):
|
||||
wantMore = false
|
||||
}
|
||||
if got := dec.More(); got != wantMore {
|
||||
t.Fatalf("%s:\n\tinput: %s\n\tdec.More() = %v, want %v (next token: %T(%v))", tt.Where, tt.json, got, wantMore, want, want)
|
||||
}
|
||||
|
||||
if dt, ok := want.(decodeThis); ok {
|
||||
want = dt.v
|
||||
err = dec.Decode(&got)
|
||||
|
||||
@ -197,6 +197,9 @@ func (d Delim) String() string {
|
||||
// to mark the start and end of arrays and objects.
|
||||
// Commas and colons are elided.
|
||||
func (dec *Decoder) Token() (Token, error) {
|
||||
if dec.err != nil {
|
||||
return nil, dec.err
|
||||
}
|
||||
tok, err := dec.dec.ReadToken()
|
||||
if err != nil {
|
||||
// Historically, v1 would report just [io.EOF] if
|
||||
@ -238,7 +241,20 @@ func (dec *Decoder) Token() (Token, error) {
|
||||
func (dec *Decoder) More() bool {
|
||||
dec.hadPeeked = true
|
||||
k := dec.dec.PeekKind()
|
||||
return k > 0 && k != ']' && k != '}'
|
||||
if k == 0 {
|
||||
if dec.err == nil {
|
||||
// PeekKind doesn't distinguish between EOF and error,
|
||||
// so read the next token to see which we get.
|
||||
_, err := dec.dec.ReadToken()
|
||||
if err == nil {
|
||||
// This is only possible if jsontext violates its documentation.
|
||||
err = errors.New("json: successful read after failed peek")
|
||||
}
|
||||
dec.err = transformSyntacticError(err)
|
||||
}
|
||||
return dec.err != io.EOF
|
||||
}
|
||||
return k != ']' && k != '}'
|
||||
}
|
||||
|
||||
// InputOffset returns the input stream byte offset of the current decoder position.
|
||||
|
||||
@ -439,6 +439,9 @@ func TestDecodeInStream(t *testing.T) {
|
||||
{CaseName: Name(""), json: ` \a`, expTokens: []any{
|
||||
&SyntaxError{"invalid character '\\\\' looking for beginning of value", len64(` `)},
|
||||
}},
|
||||
{CaseName: Name(""), json: `,`, expTokens: []any{
|
||||
&SyntaxError{"invalid character ',' looking for beginning of value", 0},
|
||||
}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
@ -447,6 +450,15 @@ func TestDecodeInStream(t *testing.T) {
|
||||
var got any
|
||||
var err error
|
||||
|
||||
wantMore := true
|
||||
switch want {
|
||||
case Delim(']'), Delim('}'):
|
||||
wantMore = false
|
||||
}
|
||||
if got := dec.More(); got != wantMore {
|
||||
t.Fatalf("%s:\n\tinput: %s\n\tdec.More() = %v, want %v (next token: %T(%v)) rem:%q", tt.Where, tt.json, got, wantMore, want, want, tt.json[dec.InputOffset():])
|
||||
}
|
||||
|
||||
if dt, ok := want.(decodeThis); ok {
|
||||
want = dt.v
|
||||
err = dec.Decode(&got)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user