Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix parseBiggestUInt to detect overflow (#24649)
With some inputs larger than `BiggestUInt.high`, `parseBiggestUInt` proc in `parseutils.nim` fails to detect overflow and returns random value. This is because `rawParseUInt` try to detects overflow with `if prev > res:` but it doesn't detects the overflow from multiplication. It is possible that `x *= 10` causes overflow and resulting value is larger than original value. Here is example values larger than `BiggestUInt.high` but `parseBiggestUInt` returns without detecting overflow: ``` 22751622367522324480000000 41404969074137497600000000 20701551093035827200000000000000000 22546225502460313600000000000000000 204963831854661632000000000000000000 ``` Following code search for values larger than `BiggestUInt.high` and `parseBiggestUInt` cannot detect overflow: ```nim import std/[strutils] const # Increase this to extend search range NBits = 34'u NBitsMax1 = 1'u shl NBits NBitsMax = NBitsMax1 - 1'u # Increase this when there are too many results and want to see only larger result. MinMultiply10 = 14 var nfound = 0 for i in (NBitsMax div 10'u + 1'u) .. NBitsMax: var x = i n10 = 0 for j in 0 ..< NBits: let px = x x = (x * 10'u) and NBitsMax if x < px: break inc n10 if n10 >= MinMultiply10: echo "i = ", i echo "uint: ", (i shl (64'u - NBits)), '0'.repeat n10 inc nfound if nfound > 15: break echo "found: ", nfound ``` (cherry picked from commit 95b1dda)
- Loading branch information