Floats and integers parsing fixes (#638)

* parser: fix scan of float with exp but no decimal
* decoder: validate leading zeros for decimals
This commit is contained in:
Thomas Pelletier
2021-10-22 22:25:56 -04:00
committed by GitHub
parent feb1830dcc
commit 4d7c9ddac7
4 changed files with 20 additions and 4 deletions
+14
View File
@@ -306,12 +306,26 @@ func parseIntBin(b []byte) (int64, error) {
return i, nil return i, nil
} }
func isSign(b byte) bool {
return b == '+' || b == '-'
}
func parseIntDec(b []byte) (int64, error) { func parseIntDec(b []byte) (int64, error) {
cleaned, err := checkAndRemoveUnderscoresIntegers(b) cleaned, err := checkAndRemoveUnderscoresIntegers(b)
if err != nil { if err != nil {
return 0, err return 0, err
} }
startIdx := 0
if isSign(cleaned[0]) {
startIdx++
}
if len(cleaned) > startIdx+1 && cleaned[startIdx] == '0' {
return 0, newDecodeError(b, "leading zero not allowed on decimal number")
}
i, err := strconv.ParseInt(string(cleaned), 10, 64) i, err := strconv.ParseInt(string(cleaned), 10, 64)
if err != nil { if err != nil {
return 0, newDecodeError(b, "couldn't parse decimal number: %w", err) return 0, newDecodeError(b, "couldn't parse decimal number: %w", err)
+1 -1
View File
@@ -958,7 +958,7 @@ byteLoop:
func (p *parser) scanIntOrFloat(b []byte) (ast.Reference, []byte, error) { func (p *parser) scanIntOrFloat(b []byte) (ast.Reference, []byte, error) {
i := 0 i := 0
if len(b) > 2 && b[0] == '0' && b[1] != '.' { if len(b) > 2 && b[0] == '0' && b[1] != '.' && b[1] != 'e' {
var isValidRune validRuneFn var isValidRune validRuneFn
switch b[1] { switch b[1] {
-3
View File
@@ -506,13 +506,11 @@ func TestTOMLTest_Invalid_Integer_LeadingZero2(t *testing.T) {
} }
func TestTOMLTest_Invalid_Integer_LeadingZeroSign1(t *testing.T) { func TestTOMLTest_Invalid_Integer_LeadingZeroSign1(t *testing.T) {
t.Skip("FIXME")
input := "leading-zero-sign-1 = -01\n" input := "leading-zero-sign-1 = -01\n"
testgenInvalid(t, input) testgenInvalid(t, input)
} }
func TestTOMLTest_Invalid_Integer_LeadingZeroSign2(t *testing.T) { func TestTOMLTest_Invalid_Integer_LeadingZeroSign2(t *testing.T) {
t.Skip("FIXME")
input := "leading-zero-sign-2 = +01\n" input := "leading-zero-sign-2 = +01\n"
testgenInvalid(t, input) testgenInvalid(t, input)
} }
@@ -1155,7 +1153,6 @@ func TestTOMLTest_Valid_Float_Underscore(t *testing.T) {
} }
func TestTOMLTest_Valid_Float_Zero(t *testing.T) { func TestTOMLTest_Valid_Float_Zero(t *testing.T) {
t.Skip("FIXME")
input := "zero = 0.0\nsigned-pos = +0.0\nsigned-neg = -0.0\nexponent = 0e0\nexponent-two-0 = 0e00\nexponent-signed-pos = +0e0\nexponent-signed-neg = -0e0\n" input := "zero = 0.0\nsigned-pos = +0.0\nsigned-neg = -0.0\nexponent = 0e0\nexponent-two-0 = 0e00\nexponent-signed-pos = +0e0\nexponent-signed-neg = -0e0\n"
jsonRef := "{\n \"zero\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"signed-pos\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"signed-neg\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-two-0\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-signed-pos\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-signed-neg\": {\n \"type\": \"float\",\n \"value\": \"0\"\n }\n}\n" jsonRef := "{\n \"zero\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"signed-pos\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"signed-neg\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-two-0\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-signed-pos\": {\n \"type\": \"float\",\n \"value\": \"0\"\n },\n \"exponent-signed-neg\": {\n \"type\": \"float\",\n \"value\": \"0\"\n }\n}\n"
testgenValid(t, input, jsonRef) testgenValid(t, input, jsonRef)
+5
View File
@@ -149,6 +149,11 @@ func TestUnmarshal_Floats(t *testing.T) {
input: `-2E-2`, input: `-2E-2`,
expected: -2e-2, expected: -2e-2,
}, },
{
desc: "float exponent zero",
input: `0e0`,
expected: 0.0,
},
{ {
desc: "float fractional with exponent", desc: "float fractional with exponent",
input: `6.626e-34`, input: `6.626e-34`,