mirror of
https://github.com/golang/go
synced 2024-11-25 08:27:57 -07:00
encoding/json: don't silently ignore error from (*Decoder).More
This commit is contained in:
parent
2f6426834c
commit
75417bfd11
@ -19,6 +19,7 @@ type Decoder struct {
|
|||||||
scanned int64 // amount of data already scanned
|
scanned int64 // amount of data already scanned
|
||||||
scan scanner
|
scan scanner
|
||||||
err error
|
err error
|
||||||
|
errFromMore bool
|
||||||
|
|
||||||
tokenState int
|
tokenState int
|
||||||
tokenStack []int
|
tokenStack []int
|
||||||
@ -48,7 +49,12 @@ func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true
|
|||||||
// the conversion of JSON into a Go value.
|
// the conversion of JSON into a Go value.
|
||||||
func (dec *Decoder) Decode(v any) error {
|
func (dec *Decoder) Decode(v any) error {
|
||||||
if dec.err != nil {
|
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 {
|
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.
|
// to mark the start and end of arrays and objects.
|
||||||
// Commas and colons are elided.
|
// Commas and colons are elided.
|
||||||
func (dec *Decoder) Token() (Token, error) {
|
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 {
|
for {
|
||||||
c, err := dec.peek()
|
c, err := dec.peek()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -481,7 +494,17 @@ func (dec *Decoder) tokenError(c byte) (Token, error) {
|
|||||||
// current array or object being parsed.
|
// current array or object being parsed.
|
||||||
func (dec *Decoder) More() bool {
|
func (dec *Decoder) More() bool {
|
||||||
c, err := dec.peek()
|
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) {
|
func (dec *Decoder) peek() (byte, error) {
|
||||||
|
@ -6,6 +6,7 @@ package json
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -520,3 +521,64 @@ func TestHTTPDecoding(t *testing.T) {
|
|||||||
t.Errorf("Decode error:\n\tgot: %v\n\twant: io.EOF", err)
|
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