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] 0x00000001 unsigned int
[0x00000001] 0x00000001 unsigned int
[0x00000002] 0x00000002 unsigned int
[0x00000003] 0x00000004 unsigned int
[0x00000004] 0x00000008 unsigned int
[0x00000005] 0x00000010 unsigned int
[0x00000006] 0x00000020 unsigned int
[0x00000007] 0x00000040 unsigned int
[0x00000008] 0x00000080 unsigned int
[0x00000009] 0x00000100 unsigned int
[0x0000000a] 0x00000200 unsigned int
[0x0000000b] 0x00000400 unsigned int
[0x0000000c] 0x00000800 unsigned int
[0x0000000d] 0x00001000 unsigned int
[0x0000000e] 0x00002000 unsigned int
[0x0000000f] 0x00004000 unsigned int
[0x00000010] 0x00008000 unsigned int
[0x00000011] 0x00010000 unsigned int
[0x00000012] 0x00020000 unsigned int
[0x00000013] 0x00040000 unsigned int
[0x00000014] 0x00080000 unsigned int
[0x00000015] 0x00100000 unsigned int
[0x00000016] 0x00200000 unsigned int
[0x00000017] 0x00400000 unsigned int
[0x00000018] 0x00800000 unsigned int
[0x00000019] 0x01000000 unsigned int
[0x0000001a] 0x02000000 unsigned int
[0x0000001b] 0x04000000 unsigned int
[0x0000001c] 0x08000000 unsigned int
[0x0000001d] 0x10000000 unsigned int
[0x0000001e] 0x20000000 unsigned int
[0x0000001f] 0x00000001 unsigned 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.