Fix parseutils.parseBiggestInt regression (#10348)

This commit is contained in:
Oscar Nihlgård 2019-01-18 19:15:29 +01:00 • committed by Andreas Rumpf
commit 86a91c1a4a

View file

@ -350,6 +350,10 @@ proc captureBetween*(s: string, first: char, second = '\0', start = 0): string =
proc integerOutOfRangeError() {.noinline.} = proc integerOutOfRangeError() {.noinline.} =
raise newException(ValueError, "Parsed integer outside of valid range") raise newException(ValueError, "Parsed integer outside of valid range")
# See #6752
when defined(js):
{.push overflowChecks: off.}
proc rawParseInt(s: string, b: var BiggestInt, start = 0): int = proc rawParseInt(s: string, b: var BiggestInt, start = 0): int =
var var
sign: BiggestInt = -1 sign: BiggestInt = -1
@ -363,18 +367,21 @@ proc rawParseInt(s: string, b: var BiggestInt, start = 0): int =
b = 0 b = 0
while i < s.len and s[i] in {'0'..'9'}: while i < s.len and s[i] in {'0'..'9'}:
let c = ord(s[i]) - ord('0') let c = ord(s[i]) - ord('0')
if b >= (low(int) + c) div 10: if b >= (low(BiggestInt) + c) div 10:
b = b * 10 - c b = b * 10 - c
else: else:
integerOutOfRangeError() integerOutOfRangeError()
inc(i) inc(i)
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
if sign == -1 and b == low(int): if sign == -1 and b == low(BiggestInt):
integerOutOfRangeError() integerOutOfRangeError()
else: else:
b = b * sign b = b * sign
result = i - start result = i - start
when defined(js):
{.pop.} # overflowChecks: off
proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {. proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {.
rtl, extern: "npuParseBiggestInt", noSideEffect, raises: [ValueError].} = rtl, extern: "npuParseBiggestInt", noSideEffect, raises: [ValueError].} =
## Parses an integer starting at `start` and stores the value into `number`. ## Parses an integer starting at `start` and stores the value into `number`.
@ -632,4 +639,8 @@ when isMainModule:
doAssert(parseSaturatedNatural("1_000_000", value) == 9) doAssert(parseSaturatedNatural("1_000_000", value) == 9)
doAssert value == 1_000_000 doAssert value == 1_000_000
var i64Value: int64
discard parseBiggestInt("9223372036854775807", i64Value)
doAssert i64Value == 9223372036854775807
{.pop.} {.pop.}