mirror of
https://github.com/json-iterator/go.git
synced 2025-02-01 19:14:29 +02:00
#138 fix - without following digits; fix 1.e1
This commit is contained in:
parent
17a26a6e20
commit
f705934fbf
@ -4,6 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -192,16 +193,9 @@ func (iter *Iterator) readFloat32SlowPath() (ret float32) {
|
|||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(str) == 0 {
|
errMsg := validateFloat(str)
|
||||||
iter.ReportError("readFloat32SlowPath", "empty number")
|
if errMsg != "" {
|
||||||
return
|
iter.ReportError("readFloat32SlowPath", errMsg)
|
||||||
}
|
|
||||||
if str[0] == '-' {
|
|
||||||
iter.ReportError("readFloat32SlowPath", "-- is not valid")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if str[len(str)-1] == '.' {
|
|
||||||
iter.ReportError("readFloat32SlowPath", "dot can not be last character")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val, err := strconv.ParseFloat(str, 32)
|
val, err := strconv.ParseFloat(str, 32)
|
||||||
@ -311,16 +305,9 @@ func (iter *Iterator) readFloat64SlowPath() (ret float64) {
|
|||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(str) == 0 {
|
errMsg := validateFloat(str)
|
||||||
iter.ReportError("readFloat64SlowPath", "empty number")
|
if errMsg != "" {
|
||||||
return
|
iter.ReportError("readFloat64SlowPath", errMsg)
|
||||||
}
|
|
||||||
if str[0] == '-' {
|
|
||||||
iter.ReportError("readFloat64SlowPath", "-- is not valid")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if str[len(str)-1] == '.' {
|
|
||||||
iter.ReportError("readFloat64SlowPath", "dot can not be last character")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val, err := strconv.ParseFloat(str, 64)
|
val, err := strconv.ParseFloat(str, 64)
|
||||||
@ -330,3 +317,25 @@ func (iter *Iterator) readFloat64SlowPath() (ret float64) {
|
|||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateFloat(str string) string {
|
||||||
|
// strconv.ParseFloat is not validating `1.` or `1.e1`
|
||||||
|
if len(str) == 0 {
|
||||||
|
return "empty number"
|
||||||
|
}
|
||||||
|
if str[0] == '-' {
|
||||||
|
return "-- is not valid"
|
||||||
|
}
|
||||||
|
dotPos := strings.IndexByte(str, '.')
|
||||||
|
if dotPos != -1 {
|
||||||
|
if dotPos == len(str)-1 {
|
||||||
|
return "dot can not be last character"
|
||||||
|
}
|
||||||
|
switch str[dotPos+1] {
|
||||||
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
|
default:
|
||||||
|
return "missing digit after dot"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -36,6 +36,9 @@ func (iter *Iterator) trySkipNumber() bool {
|
|||||||
default:
|
default:
|
||||||
switch c {
|
switch c {
|
||||||
case ',', ']', '}', ' ', '\t', '\n', '\r':
|
case ',', ']', '}', ' ', '\t', '\n', '\r':
|
||||||
|
if iter.head == i {
|
||||||
|
return false // if - without following digits
|
||||||
|
}
|
||||||
iter.head = i
|
iter.head = i
|
||||||
return true // must be valid
|
return true // must be valid
|
||||||
}
|
}
|
||||||
|
@ -68,64 +68,33 @@ func Test_invalid_array_input(t *testing.T) {
|
|||||||
should.NotNil(Unmarshal(input, &obj))
|
should.NotNil(Unmarshal(input, &obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_double_negative(t *testing.T) {
|
func Test_invalid_float(t *testing.T) {
|
||||||
should := require.New(t)
|
inputs := []string{
|
||||||
var v interface{}
|
`1.e1`, // dot without following digit
|
||||||
should.NotNil(json.Unmarshal([]byte(`--2`), &v))
|
`1.`, // dot can not be the last char
|
||||||
var vFloat64 float64
|
``, // empty number
|
||||||
should.NotNil(UnmarshalFromString(`--2`, &vFloat64))
|
`01`, // extra leading zero
|
||||||
var vFloat32 float32
|
`-`, // negative without digit
|
||||||
should.NotNil(UnmarshalFromString(`--2`, &vFloat32))
|
`--`, // double negative
|
||||||
var vInt int
|
`--2`, // double negative
|
||||||
should.NotNil(UnmarshalFromString(`--2`, &vInt))
|
|
||||||
iter := ParseString(ConfigDefault, `--2`)
|
|
||||||
iter.Skip()
|
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
|
||||||
should.NotNil(iter.Error)
|
|
||||||
}
|
}
|
||||||
|
for _, input := range inputs {
|
||||||
func Test_leading_zero(t *testing.T) {
|
t.Run(input, func(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
var v interface{}
|
iter := ParseString(ConfigDefault, input+",")
|
||||||
should.NotNil(json.Unmarshal([]byte(`01`), &v))
|
|
||||||
var vFloat64 float64
|
|
||||||
should.NotNil(UnmarshalFromString(`01`, &vFloat64))
|
|
||||||
var vFloat32 float32
|
|
||||||
should.NotNil(UnmarshalFromString(`01`, &vFloat32))
|
|
||||||
var vInt int
|
|
||||||
should.NotNil(UnmarshalFromString(`01`, &vInt))
|
|
||||||
iter := ParseString(ConfigDefault, `01,`)
|
|
||||||
iter.Skip()
|
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
|
||||||
should.NotNil(iter.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_empty_as_number(t *testing.T) {
|
|
||||||
should := require.New(t)
|
|
||||||
iter := ParseString(ConfigDefault, `,`)
|
|
||||||
iter.ReadFloat64()
|
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
|
||||||
should.NotNil(iter.Error)
|
|
||||||
iter = ParseString(ConfigDefault, `,`)
|
|
||||||
iter.ReadFloat32()
|
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
|
||||||
should.NotNil(iter.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_missing_digit_after_dot(t *testing.T) {
|
|
||||||
should := require.New(t)
|
|
||||||
iter := ParseString(ConfigDefault, `1.,`)
|
|
||||||
iter.Skip()
|
iter.Skip()
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
should.NotEqual(io.EOF, iter.Error)
|
||||||
should.NotNil(iter.Error)
|
should.NotNil(iter.Error)
|
||||||
v := float64(0)
|
v := float64(0)
|
||||||
should.NotNil(json.Unmarshal([]byte(`1.`), &v))
|
should.NotNil(json.Unmarshal([]byte(input), &v))
|
||||||
iter = ParseString(ConfigDefault, `1.`)
|
iter = ParseString(ConfigDefault, input+",")
|
||||||
iter.ReadFloat64()
|
iter.ReadFloat64()
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
should.NotEqual(io.EOF, iter.Error)
|
||||||
should.NotNil(iter.Error)
|
should.NotNil(iter.Error)
|
||||||
iter = ParseString(ConfigDefault, `1.`)
|
iter = ParseString(ConfigDefault, input+",")
|
||||||
iter.ReadFloat32()
|
iter.ReadFloat32()
|
||||||
should.NotEqual(io.EOF, iter.Error)
|
should.NotEqual(io.EOF, iter.Error)
|
||||||
should.NotNil(iter.Error)
|
should.NotNil(iter.Error)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user