Skip to content

Commit

Permalink
json-iterator#136 strconv.ParseFloat can not validate 1. , added extr…
Browse files Browse the repository at this point in the history
…a validation for this special case
  • Loading branch information
taowen committed Jul 18, 2017
1 parent 0dcb324 commit a9ae5da
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
16 changes: 16 additions & 0 deletions feature_iter_float.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jsoniter

import (
"fmt"
"io"
"math/big"
"strconv"
Expand Down Expand Up @@ -129,6 +130,9 @@ non_decimal_loop:
if c == '.' {
i++
decimalPlaces := 0
if i == iter.tail {
return iter.readFloat32SlowPath()
}
for ; i < iter.tail; i++ {
c = iter.buf[i]
ind := floatDigits[c]
Expand Down Expand Up @@ -197,6 +201,10 @@ func (iter *Iterator) readFloat32SlowPath() (ret float32) {
iter.ReportError("readFloat32SlowPath", "-- is not valid")
return
}
if str[len(str)-1] == '.' {
iter.ReportError("readFloat32SlowPath", "dot can not be last character")
return
}
val, err := strconv.ParseFloat(str, 32)
if err != nil {
iter.Error = err
Expand Down Expand Up @@ -270,6 +278,9 @@ non_decimal_loop:
if c == '.' {
i++
decimalPlaces := 0
if i == iter.tail {
return iter.readFloat64SlowPath()
}
for ; i < iter.tail; i++ {
c = iter.buf[i]
ind := floatDigits[c]
Expand Down Expand Up @@ -309,10 +320,15 @@ func (iter *Iterator) readFloat64SlowPath() (ret float64) {
iter.ReportError("readFloat64SlowPath", "-- is not valid")
return
}
if str[len(str)-1] == '.' {
iter.ReportError("readFloat64SlowPath", "dot can not be last character")
return
}
val, err := strconv.ParseFloat(str, 64)
if err != nil {
iter.Error = err
return
}
fmt.Println(str)
return val
}
13 changes: 11 additions & 2 deletions feature_iter_skip_strict.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ func (iter *Iterator) trySkipNumber() bool {
if dotFound {
iter.ReportError("validateNumber", `more than one dot found in number`)
return true // already failed
} else {
dotFound = true
}
if i+1 == iter.tail {
return false
}
c = iter.buf[i+1]
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
default:
iter.ReportError("validateNumber", `missing digit after dot`)
return true // already failed
}
dotFound = true
default:
switch c {
case ',', ']', '}', ' ', '\t', '\n', '\r':
Expand Down
18 changes: 18 additions & 0 deletions jsoniter_invalid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,21 @@ func Test_empty_as_number(t *testing.T) {
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()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
v := float64(0)
should.NotNil(json.Unmarshal([]byte(`1.`), &v))
iter = ParseString(ConfigDefault, `1.`)
iter.ReadFloat64()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
iter = ParseString(ConfigDefault, `1.`)
iter.ReadFloat32()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
}
1 change: 1 addition & 0 deletions skip_tests/number/inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ var inputs = []string{
"1E1", // valid, e or E
"1ee1", // invalid
"100a", // invalid
"10.", // invalid
}

0 comments on commit a9ae5da

Please sign in to comment.