gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit c839e7c615a3a1332753a97398ba4a28c9c7ee8b
parent 76ee8ffba42b86b46b71bf32ac0d15ccd5f871f3
Author: francoispqt <francois@parquet.ninja>
Date:   Mon, 21 May 2018 22:12:36 +0800

fix potential panics when exponents are too big

Diffstat:
Mdecode_number_int.go | 205++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mdecode_number_int_test.go | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdecode_stream.go | 2+-
Mdecode_string_unicode.go | 4++--
4 files changed, 333 insertions(+), 68 deletions(-)

diff --git a/decode_number_int.go b/decode_number_int.go @@ -29,7 +29,7 @@ func (dec *Decoder) decodeInt(v *int) error { return nil case '-': dec.cursor = dec.cursor + 1 - val, err := dec.getInt64() + val, err := dec.getInt64Negative() if err != nil { return err } @@ -58,7 +58,7 @@ func (dec *Decoder) decodeInt(v *int) error { return nil } } - return InvalidJSONError("Invalid JSON while parsing int") + return dec.raiseInvalidJSONErr(dec.cursor) } // DecodeInt16 reads the next JSON-encoded value from its input and stores it in the int16 pointed to by v. @@ -77,7 +77,7 @@ func (dec *Decoder) decodeInt16(v *int16) error { continue // we don't look for 0 as leading zeros are invalid per RFC case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt16(c) + val, err := dec.getInt16() if err != nil { return err } @@ -85,7 +85,7 @@ func (dec *Decoder) decodeInt16(v *int16) error { return nil case '-': dec.cursor = dec.cursor + 1 - val, err := dec.getInt16(dec.data[dec.cursor]) + val, err := dec.getInt16Negative() if err != nil { return err } @@ -111,7 +111,20 @@ func (dec *Decoder) decodeInt16(v *int16) error { return dec.raiseInvalidJSONErr(dec.cursor) } -func (dec *Decoder) getInt16(b byte) (int16, error) { +func (dec *Decoder) getInt16Negative() (int16, error) { + // look for following numbers + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return dec.getInt16() + default: + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + } + return 0, dec.raiseInvalidJSONErr(dec.cursor) +} + +func (dec *Decoder) getInt16() (int16, error) { var end = dec.cursor var start = dec.cursor // look for following numbers @@ -147,11 +160,15 @@ func (dec *Decoder) getInt16(b byte) (int16, error) { // then we add both integers // then we divide the number by the power found afterDecimal := dec.atoi16(startDecimal, endDecimal) - pow := pow10uint64[endDecimal-startDecimal+2] + expI := endDecimal - startDecimal + 2 + if expI >= len(pow10uint64) || expI < 0 { + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + pow := pow10uint64[expI] floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) // we have the floating value, now multiply by the exponent exp := dec.getExponent() - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= int64(len(pow10uint64)) || exp < 0 { return 0, dec.raiseInvalidJSONErr(dec.cursor) } val := floatVal * float64(pow10uint64[exp+1]) @@ -161,13 +178,14 @@ func (dec *Decoder) getInt16(b byte) (int16, error) { return dec.atoi16(start, end), nil default: dec.cursor = j - return 0, InvalidJSONError(fmt.Sprintf(invalidJSONCharErrorMsg, dec.data[dec.cursor], dec.cursor)) + return 0, dec.raiseInvalidJSONErr(dec.cursor) } } return dec.atoi16(start, end), nil case 'e', 'E': // get init n - return dec.getInt16WithExp(dec.atoi16(start, end), j+1) + dec.cursor = j + 1 + return dec.getInt16WithExp(dec.atoi16(start, end)) case ' ', '\n', '\t', '\r', ',', '}', ']': dec.cursor = j return dec.atoi16(start, end), nil @@ -178,26 +196,26 @@ func (dec *Decoder) getInt16(b byte) (int16, error) { return dec.atoi16(start, end), nil } -func (dec *Decoder) getInt16WithExp(init int16, cursor int) (int16, error) { +func (dec *Decoder) getInt16WithExp(init int16) (int16, error) { var exp uint16 var sign = int16(1) - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '+': continue case '-': sign = -1 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint16(digits[dec.data[cursor]]) + uintv := uint16(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv - cursor++ - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + dec.cursor++ + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint16(digits[dec.data[cursor]]) + uintv := uint16(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv case ' ', '\t', '\n', '}', ',', ']': - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint16(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -205,10 +223,10 @@ func (dec *Decoder) getInt16WithExp(init int16, cursor int) (int16, error) { } return init * int16(pow10uint64[exp+1]), nil default: - return 0, InvalidJSONError(fmt.Sprintf(invalidJSONCharErrorMsg, dec.data[dec.cursor], dec.cursor)) + return 0, dec.raiseInvalidJSONErr(dec.cursor) } } - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint16(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -238,7 +256,7 @@ func (dec *Decoder) decodeInt8(v *int8) error { continue // we don't look for 0 as leading zeros are invalid per RFC case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt8(c) + val, err := dec.getInt8() if err != nil { return err } @@ -246,7 +264,7 @@ func (dec *Decoder) decodeInt8(v *int8) error { return nil case '-': dec.cursor = dec.cursor + 1 - val, err := dec.getInt8(dec.data[dec.cursor]) + val, err := dec.getInt8Negative() if err != nil { return err } @@ -272,7 +290,20 @@ func (dec *Decoder) decodeInt8(v *int8) error { return dec.raiseInvalidJSONErr(dec.cursor) } -func (dec *Decoder) getInt8(b byte) (int8, error) { +func (dec *Decoder) getInt8Negative() (int8, error) { + // look for following numbers + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return dec.getInt8() + default: + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + } + return 0, dec.raiseInvalidJSONErr(dec.cursor) +} + +func (dec *Decoder) getInt8() (int8, error) { var end = dec.cursor var start = dec.cursor // look for following numbers @@ -308,11 +339,15 @@ func (dec *Decoder) getInt8(b byte) (int8, error) { // then we add both integers // then we divide the number by the power found afterDecimal := dec.atoi8(startDecimal, endDecimal) - pow := pow10uint64[endDecimal-startDecimal+2] + expI := endDecimal - startDecimal + 2 + if expI >= len(pow10uint64) || expI < 0 { + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + pow := pow10uint64[expI] floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) // we have the floating value, now multiply by the exponent exp := dec.getExponent() - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= int64(len(pow10uint64)) || exp < 0 { return 0, dec.raiseInvalidJSONErr(dec.cursor) } val := floatVal * float64(pow10uint64[exp+1]) @@ -328,7 +363,8 @@ func (dec *Decoder) getInt8(b byte) (int8, error) { return dec.atoi8(start, end), nil case 'e', 'E': // get init n - return dec.getInt8WithExp(dec.atoi8(start, end), j+1) + dec.cursor = j + 1 + return dec.getInt8WithExp(dec.atoi8(start, end)) case ' ', '\n', '\t', '\r', ',', '}', ']': dec.cursor = j return dec.atoi8(start, end), nil @@ -339,26 +375,26 @@ func (dec *Decoder) getInt8(b byte) (int8, error) { return dec.atoi8(start, end), nil } -func (dec *Decoder) getInt8WithExp(init int8, cursor int) (int8, error) { +func (dec *Decoder) getInt8WithExp(init int8) (int8, error) { var exp uint8 var sign = int8(1) - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '+': continue case '-': sign = -1 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint8(digits[dec.data[cursor]]) + uintv := uint8(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv - cursor++ - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + dec.cursor++ + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint8(digits[dec.data[cursor]]) + uintv := uint8(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv case ' ', '\t', '\n', '}', ',', ']': - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint8(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -369,7 +405,7 @@ func (dec *Decoder) getInt8WithExp(init int8, cursor int) (int8, error) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } } - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint8(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -399,7 +435,7 @@ func (dec *Decoder) decodeInt32(v *int32) error { case ' ', '\n', '\t', '\r', ',': continue case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt32(c) + val, err := dec.getInt32() if err != nil { return err } @@ -407,7 +443,7 @@ func (dec *Decoder) decodeInt32(v *int32) error { return nil case '-': dec.cursor = dec.cursor + 1 - val, err := dec.getInt32(dec.data[dec.cursor]) + val, err := dec.getInt32Negative() if err != nil { return err } @@ -432,7 +468,20 @@ func (dec *Decoder) decodeInt32(v *int32) error { return dec.raiseInvalidJSONErr(dec.cursor) } -func (dec *Decoder) getInt32(b byte) (int32, error) { +func (dec *Decoder) getInt32Negative() (int32, error) { + // look for following numbers + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return dec.getInt32() + default: + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + } + return 0, dec.raiseInvalidJSONErr(dec.cursor) +} + +func (dec *Decoder) getInt32() (int32, error) { var end = dec.cursor var start = dec.cursor // look for following numbers @@ -468,10 +517,17 @@ func (dec *Decoder) getInt32(b byte) (int32, error) { // then we add both integers // then we divide the number by the power found afterDecimal := dec.atoi64(startDecimal, endDecimal) - pow := pow10uint64[endDecimal-startDecimal+2] + expI := endDecimal - startDecimal + 2 + if expI >= len(pow10uint64) || expI < 0 { + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + pow := pow10uint64[expI] floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) // we have the floating value, now multiply by the exponent exp := dec.getExponent() + if exp+1 >= int64(len(pow10uint64)) || exp < 0 { + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } val := floatVal * float64(pow10uint64[exp+1]) return int32(val), nil case ' ', '\t', '\n', ',', ']', '}': @@ -485,7 +541,8 @@ func (dec *Decoder) getInt32(b byte) (int32, error) { return dec.atoi32(start, end), nil case 'e', 'E': // get init n - return dec.getInt32WithExp(dec.atoi32(start, end), j+1) + dec.cursor = j + 1 + return dec.getInt32WithExp(dec.atoi32(start, end)) case ' ', '\n', '\t', '\r', ',', '}', ']': dec.cursor = j return dec.atoi32(start, end), nil @@ -496,26 +553,26 @@ func (dec *Decoder) getInt32(b byte) (int32, error) { return dec.atoi32(start, end), nil } -func (dec *Decoder) getInt32WithExp(init int32, cursor int) (int32, error) { +func (dec *Decoder) getInt32WithExp(init int32) (int32, error) { var exp uint32 var sign = int32(1) - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '+': continue case '-': sign = -1 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint32(digits[dec.data[cursor]]) + uintv := uint32(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv - cursor++ - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + dec.cursor++ + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint32(digits[dec.data[cursor]]) + uintv := uint32(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv case ' ', '\t', '\n', '}', ',', ']': - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint32(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -526,7 +583,7 @@ func (dec *Decoder) getInt32WithExp(init int32, cursor int) (int32, error) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } } - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint32(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -565,7 +622,7 @@ func (dec *Decoder) decodeInt64(v *int64) error { return nil case '-': dec.cursor = dec.cursor + 1 - val, err := dec.getInt64() + val, err := dec.getInt64Negative() if err != nil { return err } @@ -590,6 +647,19 @@ func (dec *Decoder) decodeInt64(v *int64) error { return dec.raiseInvalidJSONErr(dec.cursor) } +func (dec *Decoder) getInt64Negative() (int64, error) { + // look for following numbers + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + return dec.getInt64() + default: + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + } + return 0, dec.raiseInvalidJSONErr(dec.cursor) +} + func (dec *Decoder) getInt64() (int64, error) { var end = dec.cursor var start = dec.cursor @@ -629,11 +699,15 @@ func (dec *Decoder) getInt64() (int64, error) { // then we add both integers // then we divide the number by the power found afterDecimal := dec.atoi64(startDecimal, endDecimal) - pow := pow10uint64[endDecimal-startDecimal+2] + expI := endDecimal - startDecimal + 2 + if expI >= len(pow10uint64) || expI < 0 { + return 0, dec.raiseInvalidJSONErr(dec.cursor) + } + pow := pow10uint64[expI] floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) // we have the floating value, now multiply by the exponent exp := dec.getExponent() - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= int64(len(pow10uint64)) || exp < 0 { return 0, dec.raiseInvalidJSONErr(dec.cursor) } val := floatVal * float64(pow10uint64[exp+1]) @@ -649,7 +723,8 @@ func (dec *Decoder) getInt64() (int64, error) { return dec.atoi64(start, end), nil case 'e', 'E': // get init n - return dec.getInt64WithExp(dec.atoi64(start, end), j+1) + dec.cursor = j + 1 + return dec.getInt64WithExp(dec.atoi64(start, end)) } // invalid json we expect numbers, dot (single one), comma, or spaces return 0, dec.raiseInvalidJSONErr(dec.cursor) @@ -657,26 +732,26 @@ func (dec *Decoder) getInt64() (int64, error) { return dec.atoi64(start, end), nil } -func (dec *Decoder) getInt64WithExp(init int64, cursor int) (int64, error) { +func (dec *Decoder) getInt64WithExp(init int64) (int64, error) { var exp uint64 var sign = int64(1) - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '+': continue case '-': sign = -1 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint64(digits[dec.data[cursor]]) + uintv := uint64(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv - cursor++ - for ; cursor < dec.length || dec.read(); cursor++ { - switch dec.data[cursor] { + dec.cursor++ + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint64(digits[dec.data[cursor]]) + uintv := uint64(digits[dec.data[dec.cursor]]) exp = (exp << 3) + (exp << 1) + uintv case ' ', '\t', '\n', '}', ',', ']': - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint64(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { @@ -687,7 +762,7 @@ func (dec *Decoder) getInt64WithExp(init int64, cursor int) (int64, error) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } } - if int(exp+1) >= len(pow10uint64) { + if exp+1 >= uint64(len(pow10uint64)) { return 0, dec.raiseInvalidJSONErr(dec.cursor) } if sign == -1 { diff --git a/decode_number_int_test.go b/decode_number_int_test.go @@ -38,6 +38,20 @@ func TestDecoderInt(t *testing.T) { expectedResult: 0, }, { + name: "basic-negative-err", + json: "-", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { + name: "basic-negative-err", + json: "-q", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { name: "basic-null-err", json: "nxll", expectedResult: 0, @@ -83,6 +97,12 @@ func TestDecoderInt(t *testing.T) { expectedResult: -2349557, }, { + name: "exponent-err-too-big", + json: "0e10000000000000000000", + expectedResult: 0, + err: true, + }, + { name: "basic-float", json: "2.4595", expectedResult: 2, @@ -305,6 +325,20 @@ func TestDecoderInt64(t *testing.T) { errType: InvalidJSONError(""), }, { + name: "basic-negative-err", + json: "-", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { + name: "basic-negative-err", + json: "-q", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { name: "basic-skip-data-err", json: "trua", expectedResult: 0, @@ -434,6 +468,30 @@ func TestDecoderInt64(t *testing.T) { expectedResult: -800000, }, { + name: "exponent-err-too-big", + json: "0e10000000000000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0e1000000000000000000000000 ", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1e1000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1932242242424244244e1000000000000000000000000", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-negative-positive-exp4", json: "8ea+00a5", expectedResult: 0, @@ -555,6 +613,20 @@ func TestDecoderInt32(t *testing.T) { errType: InvalidJSONError(""), }, { + name: "basic-negative-err", + json: "-", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { + name: "basic-negative-err", + json: "-q", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { name: "basic-skip-data-err", json: "trua", expectedResult: 0, @@ -611,6 +683,18 @@ func TestDecoderInt32(t *testing.T) { expectedResult: 120, }, { + name: "exponent-err-too-big", + json: "0e10000000000000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1932242242424244244e1000000000000000000000000", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-positive-positive-exp1", json: "3.5e+005 ", expectedResult: 350000, @@ -676,6 +760,36 @@ func TestDecoderInt32(t *testing.T) { expectedResult: -800000, }, { + name: "exponent-err-too-big", + json: "0.1e10000000000000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1e1000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1e1000000000 ", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0e100000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0e100000000000 ", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-err", json: "3e", expectedResult: 0, @@ -817,6 +931,20 @@ func TestDecoderInt16(t *testing.T) { errType: InvalidJSONError(""), }, { + name: "basic-negative-err", + json: "-", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { + name: "basic-negative-err", + json: "-q", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { name: "basic-skip-data-err", json: "trua", expectedResult: 0, @@ -929,6 +1057,30 @@ func TestDecoderInt16(t *testing.T) { expectedResult: -100, }, { + name: "exponent-err-too-big", + json: "0.1e10000000000000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1e10000000000 ", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0e10000000000 ", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1932242242424244244e1000000000000000000000000", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-negative-positive-exp2", json: "-5e+03", expectedResult: -5000, @@ -1078,6 +1230,20 @@ func TestDecoderInt8(t *testing.T) { expectedResult: 0, }, { + name: "basic-negative-err", + json: "-", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { + name: "basic-negative-err", + json: "-q", + expectedResult: 0, + err: true, + errType: InvalidJSONError(""), + }, + { name: "basic-null-err", json: "nxll", expectedResult: 0, @@ -1214,11 +1380,35 @@ func TestDecoderInt8(t *testing.T) { errType: InvalidJSONError(""), }, { + name: "exponent-err-too-big", + json: "0.1e10000000000000000000", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big", + json: "0.1932242242424244244e1000000000000000000000000", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-negative-positive-exp4", json: "-8e+001", expectedResult: -80, }, { + name: "exponent-err-too-big2", + json: "0e100 ", + expectedResult: 0, + err: true, + }, + { + name: "exponent-err-too-big2", + json: "0.1e100 ", + expectedResult: 0, + err: true, + }, + { name: "basic-exponent-err", json: "3e", expectedResult: 0, diff --git a/decode_stream.go b/decode_stream.go @@ -64,7 +64,7 @@ func (dec *StreamDecoder) DecodeStream(c UnmarshalerStream) error { } } close(dec.done) - return InvalidJSONError("Invalid JSON while parsing line delimited JSON") + return dec.raiseInvalidJSONErr(dec.cursor) } // context.Context implementation diff --git a/decode_string_unicode.go b/decode_string_unicode.go @@ -56,7 +56,7 @@ func (dec *Decoder) parseUnicode() ([]byte, error) { // check if code can be a surrogate utf16 if utf16.IsSurrogate(r) { if dec.cursor >= dec.length && !dec.read() { - return nil, InvalidJSONError("Invalid JSON") + return nil, dec.raiseInvalidJSONErr(dec.cursor) } c := dec.data[dec.cursor] if c != '\\' { @@ -65,7 +65,7 @@ func (dec *Decoder) parseUnicode() ([]byte, error) { } dec.cursor++ if dec.cursor >= dec.length && !dec.read() { - return nil, InvalidJSONError("Invalid JSON") + return nil, dec.raiseInvalidJSONErr(dec.cursor) } c = dec.data[dec.cursor] if c != 'u' {