Skip to content

Commit 93f67d9

Browse files
committed
fastfloat: localize handling of invalid number without integer and fractional parts
This is a follow-up for 6f52d1b
1 parent 6f52d1b commit 93f67d9

File tree

3 files changed

+13
-16
lines changed

3 files changed

+13
-16
lines changed

fastfloat/parse.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ func ParseBestEffort(s string) float64 {
215215

216216
// the integer part might be elided to remain compliant
217217
// with https://go.dev/ref/spec#Floating-point_literals
218-
intPartElided := s[i] == '.'
218+
if s[i] == '.' && (i+1 >= uint(len(s)) || s[i+1] < '0' || s[i+1] > '9') {
219+
return 0
220+
}
219221

220222
d := uint64(0)
221223
j := i
@@ -236,7 +238,7 @@ func ParseBestEffort(s string) float64 {
236238
}
237239
break
238240
}
239-
if i <= j && !intPartElided {
241+
if i <= j && s[i] != '.' {
240242
s = s[i:]
241243
if strings.HasPrefix(s, "+") {
242244
s = s[1:]
@@ -267,9 +269,6 @@ func ParseBestEffort(s string) float64 {
267269
// Parse fractional part.
268270
i++
269271
if i >= uint(len(s)) {
270-
if intPartElided {
271-
return 0
272-
}
273272
// the fractional part may be elided to remain compliant
274273
// with https://go.dev/ref/spec#Floating-point_literals
275274
return f
@@ -305,9 +304,6 @@ func ParseBestEffort(s string) float64 {
305304
}
306305
}
307306
if s[i] == 'e' || s[i] == 'E' {
308-
if intPartElided {
309-
return 0
310-
}
311307
// Parse exponent part.
312308
i++
313309
if i >= uint(len(s)) {
@@ -377,7 +373,9 @@ func Parse(s string) (float64, error) {
377373

378374
// the integer part might be elided to remain compliant
379375
// with https://go.dev/ref/spec#Floating-point_literals
380-
intPartElided := s[i] == '.'
376+
if s[i] == '.' && (i+1 >= uint(len(s)) || s[i+1] < '0' || s[i+1] > '9') {
377+
return 0, fmt.Errorf("missing integer and fractional part in %q", s)
378+
}
381379

382380
d := uint64(0)
383381
j := i
@@ -398,7 +396,7 @@ func Parse(s string) (float64, error) {
398396
}
399397
break
400398
}
401-
if i <= j && !intPartElided {
399+
if i <= j && s[i] != '.' {
402400
ss := s[i:]
403401
if strings.HasPrefix(ss, "+") {
404402
ss = ss[1:]
@@ -429,9 +427,6 @@ func Parse(s string) (float64, error) {
429427
// Parse fractional part.
430428
i++
431429
if i >= uint(len(s)) {
432-
if intPartElided {
433-
return 0, fmt.Errorf("cannot parse integer or fractional part in %q", s)
434-
}
435430
// the fractional part might be elided to remain compliant
436431
// with https://go.dev/ref/spec#Floating-point_literals
437432
return f, nil
@@ -467,9 +462,6 @@ func Parse(s string) (float64, error) {
467462
}
468463
}
469464
if s[i] == 'e' || s[i] == 'E' {
470-
if intPartElided {
471-
return 0, fmt.Errorf("cannot parse integer part in %q", s)
472-
}
473465
// Parse exponent part.
474466
i++
475467
if i >= uint(len(s)) {

fastfloat/parse_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ func TestParseSuccess(t *testing.T) {
451451
f("-123.456E-10", -123.456e-10)
452452
f("1.e4", 1.e4)
453453
f("-1.E-10", -1.e-10)
454+
f(".1e3", 100)
455+
f("-.12e3", -120)
454456

455457
// inf and nan
456458
f("12345678909123456789012e45678", math.Inf(1))

parser_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ func TestParseRawNumber(t *testing.T) {
3535
f("-12.345E+67 tail", "-12.345E+67", " tail")
3636
f("-12.345E-67,tail", "-12.345E-67", ",tail")
3737
f("-1234567.8e+90tail", "-1234567.8e+90", "tail")
38+
f("12.tail", "12.", "tail")
39+
f(".2tail", ".2", "tail")
40+
f("-.2tail", "-.2", "tail")
3841
f("NaN", "NaN", "")
3942
f("nantail", "nan", "tail")
4043
f("inf", "inf", "")

0 commit comments

Comments
 (0)