lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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:
  1. an integer
  2. follow lexical rules
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