From 8b80039cac29918b231bca5d474522d71a8ca343 Mon Sep 17 00:00:00 2001 From: flywind Date: Mon, 16 Aug 2021 21:14:35 +0800 Subject: [PATCH] fix #18702(fix `parseutils.parseFloat`) (#18703) [backport:1.0] * fix #18702 * Apply suggestions from code review (cherry picked from commit 901c5ded527bb06c52bfc1fd38c9a5fadee0f49a) --- lib/system/strmantle.nim | 9 +++++---- tests/stdlib/tparseutils.nim | 13 +++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/system/strmantle.nim b/lib/system/strmantle.nim index fa6ff411bd..6f9f08e697 100644 --- a/lib/system/strmantle.nim +++ b/lib/system/strmantle.nim @@ -240,15 +240,16 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, var ti = 0 let maxlen = t.high - "e+000".len # reserve enough space for exponent - result = i - start + let endPos = i + result = endPos - start i = start # re-parse without error checking, any error should be handled by the code above. - if i < s.len and s[i] == '.': i.inc - while i < s.len and s[i] in {'0'..'9','+','-'}: + if i < endPos and s[i] == '.': i.inc + while i < endPos and s[i] in {'0'..'9','+','-'}: if ti < maxlen: t[ti] = s[i]; inc(ti) inc(i) - while i < s.len and s[i] in {'.', '_'}: # skip underscore and decimal point + while i < endPos and s[i] in {'.', '_'}: # skip underscore and decimal point inc(i) # insert exponent diff --git a/tests/stdlib/tparseutils.nim b/tests/stdlib/tparseutils.nim index 3bc54dff19..db7a0ac8d1 100644 --- a/tests/stdlib/tparseutils.nim +++ b/tests/stdlib/tparseutils.nim @@ -1,5 +1,5 @@ -import parseutils -import sequtils +import std/[parseutils, sequtils, sugar] + let input = "$test{} $this is ${an{ example}} " let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"), @@ -41,3 +41,12 @@ doAssert value == 1_000_000 var i64Value: int64 discard parseBiggestInt("9223372036854775807", i64Value) doAssert i64Value == 9223372036854775807 + +block: + var f: float + let res = collect: + for x in ["9.123456789012345+","11.123456789012345+","9.123456789012345-","8.123456789012345+","9.12345678901234-","9.123456789012345"]: + (parseFloat(x, f, 0), $f) + doAssert res == @[(17, "9.123456789012344"), (18, "11.123456789012344"), + (17, "9.123456789012344"), (17, "8.123456789012344"), + (16, "9.12345678901234"), (17, "9.123456789012344")]