mirror of
https://github.com/golang/go
synced 2024-11-25 03:27:58 -07:00
encoding/json: don't silently ignore error from (*Decoder).More
This commit is contained in:
parent
2f6426834c
commit
75417bfd11
@ -12,13 +12,14 @@ import (
|
||||
|
||||
// A Decoder reads and decodes JSON values from an input stream.
|
||||
type Decoder struct {
|
||||
r io.Reader
|
||||
buf []byte
|
||||
d decodeState
|
||||
scanp int // start of unread data in buf
|
||||
scanned int64 // amount of data already scanned
|
||||
scan scanner
|
||||
err error
|
||||
r io.Reader
|
||||
buf []byte
|
||||
d decodeState
|
||||
scanp int // start of unread data in buf
|
||||
scanned int64 // amount of data already scanned
|
||||
scan scanner
|
||||
err error
|
||||
errFromMore bool
|
||||
|
||||
tokenState int
|
||||
tokenStack []int
|
||||
@ -48,7 +49,12 @@ func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true
|
||||
// the conversion of JSON into a Go value.
|
||||
func (dec *Decoder) Decode(v any) error {
|
||||
if dec.err != nil {
|
||||
return dec.err
|
||||
err := dec.err
|
||||
if dec.errFromMore {
|
||||
dec.err = nil
|
||||
dec.errFromMore = false
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := dec.tokenPrepareForDecode(); err != nil {
|
||||
@ -365,6 +371,13 @@ 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 && dec.errFromMore {
|
||||
err := dec.err
|
||||
dec.err = nil
|
||||
dec.errFromMore = false
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
c, err := dec.peek()
|
||||
if err != nil {
|
||||
@ -481,7 +494,17 @@ func (dec *Decoder) tokenError(c byte) (Token, error) {
|
||||
// current array or object being parsed.
|
||||
func (dec *Decoder) More() bool {
|
||||
c, err := dec.peek()
|
||||
return err == nil && c != ']' && c != '}'
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
dec.err = nil
|
||||
dec.errFromMore = false
|
||||
return false
|
||||
}
|
||||
dec.err = err
|
||||
dec.errFromMore = true
|
||||
return true
|
||||
}
|
||||
return c != ']' && c != '}'
|
||||
}
|
||||
|
||||
func (dec *Decoder) peek() (byte, error) {
|
||||
|
@ -6,6 +6,7 @@ package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@ -520,3 +521,64 @@ func TestHTTPDecoding(t *testing.T) {
|
||||
t.Errorf("Decode error:\n\tgot: %v\n\twant: io.EOF", err)
|
||||
}
|
||||
}
|
||||
|
||||
type failingDecoderTestReader struct {
|
||||
t *testing.T
|
||||
i int
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *failingDecoderTestReader) Read(b []byte) (n int, err error) {
|
||||
i := c.i
|
||||
c.i++
|
||||
|
||||
defer func() {
|
||||
c.t.Logf("%v, %v, %v, %v\n", i, len(b), n, err)
|
||||
|
||||
// Decoder always passes a buffer with size that has at least 512 Bytes. This test
|
||||
// depends on that behaviour, so that the reader does not get unnecessarily complicated.
|
||||
if len(b) == n {
|
||||
c.t.Fatal("small buffer passed to Read")
|
||||
}
|
||||
}()
|
||||
|
||||
switch i {
|
||||
case 0:
|
||||
return copy(b, `[{ "test": 1 }`), nil
|
||||
case 1:
|
||||
return 0, c.err
|
||||
default:
|
||||
return 0, io.EOF
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoderMore(t *testing.T) {
|
||||
type Message struct{ Test int }
|
||||
|
||||
notIgnoredError := errors.New("not ignored error")
|
||||
dec := NewDecoder(&failingDecoderTestReader{t: t, err: notIgnoredError})
|
||||
|
||||
if val, err := dec.Token(); err != nil || val != Delim('[') {
|
||||
t.Fatalf("(*Decoder).Token() = (%v, %v); want = ([, <nil>)", val, err)
|
||||
}
|
||||
|
||||
if err := dec.Decode(new(Message)); err != nil {
|
||||
t.Fatalf("(*Decoder).Decode() = %v; want = <nil>", err)
|
||||
}
|
||||
|
||||
if !dec.More() {
|
||||
t.Fatalf("(*Decoder).More() = false; want = true")
|
||||
}
|
||||
|
||||
if err := dec.Decode(new(Message)); err != notIgnoredError {
|
||||
t.Fatalf("(*Decoder).Decode() = %v; want = %v", err, notIgnoredError)
|
||||
}
|
||||
|
||||
if dec.More() {
|
||||
t.Fatalf("(*Decoder).More() = true; want = false")
|
||||
}
|
||||
|
||||
if err := dec.Decode(new(Message)); err != io.EOF {
|
||||
t.Fatalf("(*Decoder).Decode() = %v; want = %v", err, io.EOF)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user