|
Lua's lexical parser and lua_stringtonumber invoke luaO_str2int which correctly handles overflow (by falling back to a number (float) as opposed to integer). This is good.
However, tonumber(s[, radix]) uses its own str2int handler, which does not guard from overflow. The manual's description of tonumber says it follows the lexical rules, and that when gives a radix, the string must represent an integer. This has no mention of
overflow
The lexical rules do not mention overflow:
https://www.lua.org/manual/5.3/manual.html#3.1
Thus, if tonumber(s, radix) must be:
Then an overflow should return nil, and not an overflow-value.
on lua with 64bit integers:
repro:
local function nil_or_match( text, number )
local result = tonumber(text, 10)
assert( result == nil or result == number)
end
nil_or_match('9223372036854775807', 9223372036854775807) // pass
nil_or_match('9223372036854775808', 9223372036854775808) // fail
expected:
either the tonumber is successful with the expected value, or we get a safe failure
actual:
tonumber returns -9223372036854775808
proposed fix:
There could be a lua_Integer max value check before the unsigned->signed conversion here:
https://github.com/lua/lua/blob/master/lbaselib.c#L76
PS: I'm still hoping someone takes a lot at my first bug report:
http://lua-users.org/lists/lua-l/2020-03/msg00021.html
|