mirror of https://github.com/goccy/go-json.git
Fix stream decoding for null/true/false value
This commit is contained in:
parent
82cc22a37f
commit
2034757368
|
@ -13,54 +13,6 @@ func newBoolDecoder(structName, fieldName string) *boolDecoder {
|
||||||
return &boolDecoder{structName: structName, fieldName: fieldName}
|
return &boolDecoder{structName: structName, fieldName: fieldName}
|
||||||
}
|
}
|
||||||
|
|
||||||
func trueBytes(s *stream) error {
|
|
||||||
if s.cursor+3 >= s.length {
|
|
||||||
if !s.read() {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'r' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'u' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'e' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func falseBytes(s *stream) error {
|
|
||||||
if s.cursor+4 >= s.length {
|
|
||||||
if !s.read() {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'a' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'l' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 's' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'e' {
|
|
||||||
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *boolDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
func (d *boolDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -313,3 +313,102 @@ func (s *stream) skipValue(depth int64) error {
|
||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nullBytes(s *stream) error {
|
||||||
|
// current cursor's character is 'n'
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'u' {
|
||||||
|
if err := retryReadNull(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'l' {
|
||||||
|
if err := retryReadNull(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'l' {
|
||||||
|
if err := retryReadNull(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func retryReadNull(s *stream) error {
|
||||||
|
if s.char() == nul && s.read() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errInvalidCharacter(s.char(), "null", s.totalOffset())
|
||||||
|
}
|
||||||
|
|
||||||
|
func trueBytes(s *stream) error {
|
||||||
|
// current cursor's character is 't'
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'r' {
|
||||||
|
if err := retryReadTrue(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'u' {
|
||||||
|
if err := retryReadTrue(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'e' {
|
||||||
|
if err := retryReadTrue(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func retryReadTrue(s *stream) error {
|
||||||
|
if s.char() == nul && s.read() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
|
||||||
|
}
|
||||||
|
|
||||||
|
func falseBytes(s *stream) error {
|
||||||
|
// current cursor's character is 'f'
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'a' {
|
||||||
|
if err := retryReadFalse(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'l' {
|
||||||
|
if err := retryReadFalse(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 's' {
|
||||||
|
if err := retryReadFalse(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
if s.char() != 'e' {
|
||||||
|
if err := retryReadFalse(s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.cursor++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func retryReadFalse(s *stream) error {
|
||||||
|
if s.char() == nul && s.read() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
|
||||||
|
}
|
||||||
|
|
|
@ -233,28 +233,6 @@ ERROR:
|
||||||
return nil, errUnexpectedEndOfJSON("string", s.totalOffset())
|
return nil, errUnexpectedEndOfJSON("string", s.totalOffset())
|
||||||
}
|
}
|
||||||
|
|
||||||
func nullBytes(s *stream) error {
|
|
||||||
if s.cursor+3 >= s.length {
|
|
||||||
if !s.read() {
|
|
||||||
return errInvalidCharacter(s.char(), "null", s.totalOffset())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'u' {
|
|
||||||
return errInvalidCharacter(s.char(), "null", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'l' {
|
|
||||||
return errInvalidCharacter(s.char(), "null", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
if s.char() != 'l' {
|
|
||||||
return errInvalidCharacter(s.char(), "null", s.totalOffset())
|
|
||||||
}
|
|
||||||
s.cursor++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *stringDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
func (d *stringDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
|
|
@ -32,6 +32,15 @@ func TestValid(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidWithComplexData(t *testing.T) {
|
||||||
|
data := []byte(`{"ABCDEFGHIJKL":[{"MNOPQRSTUVWX":[{"YABC":{"DEFG":[{"HIJKLMNO":{"PQRS":"TUVWXYABCDEFGHIJKLMNOPQRSTUVWXYABCDEFGHIJKLMNOPQRSTUVWXYABCDE","FGHIJKLM":"NOPQRSTUVW"},"XYABCDEFGH":[{"IJKLMNOP":"!=","Q":{"RSTU":"V","WXYABCDE":"FGHIJKLMNO"},"P":{"QRSTUVWX":"YAB"},"CDEFGHIJ":"KLMNOP","QRSTUVWX":"YABCDEFGHI"}],"JKLMNOPQRSTUVW":null,"XYABCDEF":"GHIJ"},{"KLMNOPQR":{"STUVWXY":{"ABCDEFGH":"IJKLMN_OPQ_RST","U":{"VWXY":"A","BCDEFGHI":"JKLMNOPQRS"},"TUVWXYAB":"CDEFG","HIJKLMNO":"PQRSTUVWXY"},"ABCDEFGH":"IJKLMNOP!Q41R8ST98U00V204W9800998XYA8427B","CDEFGHIJ":"KLMNOP","QRSTUVWX":"YABCDEFGHI"},"JKLMNOPQRS":null,"TUVWXYABCDEFGH":null,"IJKLMNOP":"QRST"}],"UVWXYABC":"DEFGH","IJKLMNOP":"QRSTUVWXY"},"ABCDEFGH":9,"IJKL":"MNOPQRST/UVWXYABCDE//FGHIJKLMNOPQRST!4UV2WXYABC7826D7659EF223GH40I91J","KLMNOPQRST":[{"UVWXYABCDEFG":null,"HIJKLMNO":0,"PQRS":"T","UVWX":{"YABC":{"DEFG":"HIJK/LMNO/PQRSTU","VWXYABCD":"EFGHIJKLM","NOPQRSTU":"VWXY"},"ABCDEFGH":"IJKLMNO","PQRSTUVW":"XYAB"},"CDEFGHIJ":"KLMNOPQR"}],"STUVWXYA":null,"BCDEFGH":null,"IJKLMN":null,"OPQRSTUVWXYABC":null,"DEFGHIJK":"LMNOPQRS"},{"TUVW":{"XYAB":[{"CDEFGHIJ":{"KLMN":"OPQRSTUV/WXYABCDEFG//HIJKLMNOPQRSTUV!4WX2YABCDE7826F7659GH223IJ40K91L","MNOPQRST":"UVWXYABCDE"},"FGHIJKLMNO":[{"PQRS":"T","UVWXYABC":"DEFGHIJKLM"}],"NOPQRSTUVWXYAB":null,"CDEFGHIJ":"KLMN"}],"OPQRSTUV":"WXYAB","CDEFGHIJ":"KLMNOPQRS"},"TUVWXYAB":9,"CDEF":"GHIJKLMN/OPQRSTUVWX//YABCDEFGHIJKLM!4NO2PQRSTU7826V7659WX223YA40B91C","DEFGHIJKLM":[{"NOPQRSTUVWXY":null,"ABCDEFGH":0,"IJKL":"M","NOPQ":{"RSTU":{"VWXY":"ABCD/EFGH/IJKLMN","OPQRSTUV":"WXYABCDEF","GHIJKLMN":"OPQR"},"STUVWXYA":"BCDEFGH","IJKLMNOP":"QRST"},"UVWXYABC":"DEFGHIJK"}],"LMNOPQRS":null,"TUVWXYA":null,"BCDEFG":null,"HIJKLMNOPQRSTU":null,"VWXYABCD":"EFGHIJKL"},{"MNOP":{"QRST":[{"UVWXYABC":0,"DEFG":["HIJK"],"LMNO":[{"PQRS":{"TUVW":"XYABCDEF/GHIJKLMNOP","QRSTUVWX":"YABCDEFGH","IJKLMNOP":"QRST"},"UVWXYABC":"DEFGHIJ","KLMNOPQR":"STUV"}],"WXYAB":[{"CDEF":{"GHIJ":{"KLMN":"OPQRSTUV/WXYABCDEFG","HIJKLMNO":"PQRSTUVWX","YABCDEFG":"HIJK"},"LMNOPQRS":"TUVWXYA","BCDEFGHI":"JKLM"},"NOPQRSTU":"VWX"}],"YABCDEFG":"HIJKLMNOPQR","STUVWXYA":"BCDEFGHIJ"},{"KLMNOPQR":"=","S":{"TUVWXYA":{"BCDE":"FGHI","JKLMNOPQ":"RSTUVWXYAB"},"CDEFGHIJ":"@KLMN/OPQR/STUVWX","YABCDEFG":"HIJKLM","NOPQRSTU":"VWXYABCDEF"},"G":{"HIJKLMNO":{"PQRS":"TUVW/XYAB/CDEFGH//IJKLMN!O41P8QR98S00T204U9800998VWX8427Y","ABCDEFGH":"IJKLMNOPQR"},"STUVWXYABC":null,"DEFGHIJKLMNOPQ":null,"RSTUVWXY":"ABCD"},"EFGHIJKL":"MNOPQR","STUVWXYA":"BCDEFGHIJK"},{"LMNOPQR":[{"STUV":"WXYA","BCDEFGHI":"JKLMNOPQRS"}],"TUVWXYAB":"CDEFGH","IJKLMNOP":"QRSTUVWXY"}],"ABCDEFGH":"IJKLM","NOPQRSTU":"VWXYABCDE"},"FGHIJKLM":37,"NOPQ":"RSTUVWXY/ABCDEFGHIJ//KLMNOPQRST!U41V8WX98Y00A204B9800998CDE8427F","GHIJKLMNOP":null,"QRSTUVWX":null,"YABCDEF":[{"GHIJKLMNOPQR":null,"STUVWXYA":0,"BCDE":"","FGHI":{"JKLM":{"NOPQ":"RSTUVWXY/ABCDEFGHIJ","KLMNOPQR":"STUVWXYAB","CDEFGHIJ":"KLMN"},"OPQRSTUV":"WXYABCD","EFGHIJKL":"MNOP"},"QRSTUVWX":"YABCDEFG"}],"HIJKLM":null,"NOPQRSTUVWXYAB":null,"CDEFGHIJ":"KLMNOPQR"}],"STUVWXYABC":null,"DEFGHIJK":[{"LMNO":{"PQRS":"TUVW/XYAB/CDEFGH","IJKLMNOP":"QRSTUVWXY","ABCDEFGH":"IJKL"},"MNOPQRST":"UVWXYAB","CDEFGHIJ":"KLMN"}],"OPQRSTUV":1,"WXYA":"BCDEFGHI/JKLMNOPQRS","TUVWXYAB":null,"CDEFGHIJKLMNOP":null,"QRSTUVWX":"YABCDE","FGHIJKLM":"NOPQ"}]}`)
|
||||||
|
expected := stdjson.Valid(data)
|
||||||
|
actual := json.Valid(data)
|
||||||
|
if expected != actual {
|
||||||
|
t.Fatalf("failed to valid: expected %v but got %v", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type example struct {
|
type example struct {
|
||||||
compact string
|
compact string
|
||||||
indent string
|
indent string
|
||||||
|
|
Loading…
Reference in New Issue