summaryrefslogtreecommitdiff
path: root/decode_scan.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-25 20:42:37 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-25 20:42:37 -0700
commit0fa9f8b14f04f4b0099f038cc43e4cef57a155a1 (patch)
tree62a21db8d3241bcf264bcf0874df632c4ce9ba94 /decode_scan.go
parent03778c094d995791f6c3df08afeeb792f33f35a5 (diff)
parent22edcf6a68a057ed04368d5f78c8ba3ddfee8d57 (diff)
Merge branch 'lukeshu/fuzz-err'
Diffstat (limited to 'decode_scan.go')
-rw-r--r--decode_scan.go28
1 files changed, 22 insertions, 6 deletions
diff --git a/decode_scan.go b/decode_scan.go
index 63694c4..7ef3e71 100644
--- a/decode_scan.go
+++ b/decode_scan.go
@@ -6,6 +6,7 @@ package lowmemjson
import (
"io"
+ "unicode/utf8"
"git.lukeshu.com/go/lowmemjson/internal/jsonparse"
)
@@ -22,10 +23,11 @@ type runeTypeScanner struct {
rTypeOK bool
repeat bool
- rRune rune
- rSize int
- rType jsonparse.RuneType
- rErr error
+ rRune rune
+ rSize int
+ rIsRune bool
+ rType jsonparse.RuneType
+ rErr error
}
// The returned error is a *ReadError, a *SyntaxError, or nil.
@@ -55,7 +57,18 @@ func (sc *runeTypeScanner) ReadRuneType() (rune, int, jsonparse.RuneType, error)
sc.offset += int64(sc.rSize)
switch err {
case nil:
- sc.rType, err = sc.parser.HandleRune(sc.rRune)
+ sc.rIsRune = true
+ if sc.rRune == utf8.RuneError && sc.rSize == 1 {
+ if bs, ok := sc.inner.(io.ByteScanner); ok {
+ _ = bs.UnreadByte() // UnreadRune doesn't back up the ReadByte-pos
+ b, _ := bs.ReadByte()
+ _ = bs.UnreadByte()
+ _, _, _ = sc.inner.ReadRune()
+ sc.rRune = rune(b)
+ sc.rIsRune = false
+ }
+ }
+ sc.rType, err = sc.parser.HandleRune(sc.rRune, sc.rIsRune)
if err != nil {
sc.rErr = &DecodeSyntaxError{
Offset: sc.offset - int64(sc.rSize),
@@ -92,6 +105,9 @@ func (sc *runeTypeScanner) ReadRuneType() (rune, int, jsonparse.RuneType, error)
}
}
sc.repeat = false
+ if sc.rSize > 0 && !sc.rIsRune {
+ return utf8.RuneError, sc.rSize, sc.rType, sc.rErr
+ }
return sc.rRune, sc.rSize, sc.rType, sc.rErr
}
@@ -124,7 +140,7 @@ func (sc *runeTypeScanner) PopReadBarrier() {
case sc.repeat:
// re-figure the rType and rErr
var err error
- sc.rType, err = sc.parser.HandleRune(sc.rRune)
+ sc.rType, err = sc.parser.HandleRune(sc.rRune, sc.rIsRune)
if err != nil {
sc.rErr = &DecodeSyntaxError{
Offset: sc.offset - int64(sc.rSize),