Skip to content

Commit 8fd342d

Browse files
committed
GODRIVER-700: fix issue with EOF handling in the json scanner when io.Reader returns n > 0 and io.EOF.
Change-Id: Ibad8c2dcada1f5ea0d88129681cdf1d57f51f9a3
1 parent 6310dd3 commit 8fd342d

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

bson/bsonrw/json_scanner.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ type jsonToken struct {
4242
}
4343

4444
type jsonScanner struct {
45-
r io.Reader
46-
buf []byte
47-
pos int
45+
r io.Reader
46+
buf []byte
47+
pos int
48+
lastReadErr error
4849
}
4950

5051
// nextToken returns the next JSON token if one exists. A token is a character
@@ -126,11 +127,23 @@ func (js *jsonScanner) readNNextBytes(dst []byte, n, offset int) error {
126127

127128
// readIntoBuf reads up to 512 bytes from the scanner's io.Reader into the buffer
128129
func (js *jsonScanner) readIntoBuf() error {
130+
if js.lastReadErr != nil {
131+
js.buf = js.buf[:0]
132+
js.pos = 0
133+
return js.lastReadErr
134+
}
135+
129136
if cap(js.buf) == 0 {
130137
js.buf = make([]byte, 0, 512)
131138
}
132139

133140
n, err := js.r.Read(js.buf[:cap(js.buf)])
141+
if err != nil {
142+
js.lastReadErr = err
143+
if n > 0 {
144+
err = nil
145+
}
146+
}
134147
js.buf = js.buf[:n]
135148
js.pos = 0
136149

bson/bsonrw/json_scanner_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package bsonrw
99
import (
1010
"strings"
1111
"testing"
12+
"testing/iotest"
1213

1314
"github.com/google/go-cmp/cmp"
1415
)
@@ -282,6 +283,20 @@ func TestJsonScannerValidInputs(t *testing.T) {
282283
c, err := js.nextToken()
283284
jttDiff(t, jttEOF, c.t, tc.desc)
284285
noerr(t, err)
286+
287+
// testing early EOF reading
288+
js = &jsonScanner{r: iotest.DataErrReader(strings.NewReader(tc.input))}
289+
290+
for _, token := range tc.tokens {
291+
c, err := js.nextToken()
292+
jttDiff(t, token.t, c.t, tc.desc)
293+
jtvDiff(t, token.v, c.v, tc.desc)
294+
expectNoError(t, err, tc.desc)
295+
}
296+
297+
c, err = js.nextToken()
298+
jttDiff(t, jttEOF, c.t, tc.desc)
299+
noerr(t, err)
285300
}
286301
}
287302

0 commit comments

Comments
 (0)