This code:
local t = {}
for i = 1, 0x7fffffff do
t[i] = i
end
crashes the interpreter as soon as i becomes 0x40000001. within the call to computesizes(). Here is the relevant portion of the stack:
computesizes(unsigned int * nums, unsigned int * pna) Line 229
rehash(lua_State * L, Table * t, const lua_TValue * ek) Line 392
luaH_newkey(lua_State * L, Table * t, const lua_TValue * key) Line 462
luaV_finishset(lua_State * L, const lua_TValue * t, lua_TValue * key, lua_TValue * val, const lua_TValue * slot) Line 214
luaV_execute(lua_State * L) Line 864
luaD_call(lua_State * L, lua_TValue * func, int nResults) Line 497
luaD_callnoyield(lua_State * L, lua_TValue * func, int nResults) Line 507
f_call(lua_State * L, void * ud) Line 943
luaD_rawrunprotected(lua_State * L, void(*)(lua_State *, void *) f, void * ud) Line 142
luaD_pcall(lua_State * L, void(*)(lua_State *, void *) func, void * u, __int64 old_top, __int64 ef) Line 727
lua_pcallk(lua_State * L, int nargs, int nresults, int errfunc, __int64 ctx, int(*)(lua_State *, int, __int64) k) Line 968
The Lua version is 5.3.3, as far as I can tell no relevant changes were made in 5.3.4.
The particular configuration I have encountered and reproduced this on is Windows 8.1, 64-bit mode, but I think this is not Windows-specific.
The crash happens in line 229 of ltable.c, where it has if (nums[i] > 0).
nums is passed from rehash, where it is defined to be an array of 32 unsigned ints. At the time of the crash, i is 1848, way outside the array bounds. The first 31 elements of nums at the time of crash are:
[0x00000000]0x00000001unsigned int
[0x00000001]0x00000001unsigned int
[0x00000002]0x00000002unsigned int
[0x00000003]0x00000004unsigned int
[0x00000004]0x00000008unsigned int
[0x00000005]0x00000010unsigned int
[0x00000006]0x00000020unsigned int
[0x00000007]0x00000040unsigned int
[0x00000008]0x00000080unsigned int
[0x00000009]0x00000100unsigned int
[0x0000000a]0x00000200unsigned int
[0x0000000b]0x00000400unsigned int
[0x0000000c]0x00000800unsigned int
[0x0000000d]0x00001000unsigned int
[0x0000000e]0x00002000unsigned int
[0x0000000f]0x00004000unsigned int
[0x00000010]0x00008000unsigned int
[0x00000011]0x00010000unsigned int
[0x00000012]0x00020000unsigned int
[0x00000013]0x00040000unsigned int
[0x00000014]0x00080000unsigned int
[0x00000015]0x00100000unsigned int
[0x00000016]0x00200000unsigned int
[0x00000017]0x00400000unsigned int
[0x00000018]0x00800000unsigned int
[0x00000019]0x01000000unsigned int
[0x0000001a]0x02000000unsigned int
[0x0000001b]0x04000000unsigned int
[0x0000001c]0x08000000unsigned int
[0x0000001d]0x10000000unsigned int
[0x0000001e]0x20000000unsigned int
[0x0000001f]0x00000001unsigned int
And to be clear, I do not assume that Lua should have infinite tables. It would be good to get a regular Lua error like "table too big" when a table becomes too big, but not a crash.
Another thing I noticed is that the maximum table length (for whatever meaning of length) is not mentioned in the documentation, nor is the behaviour when an attempt is made to exceed it.
Cheers,
V.