lua-users home
lua-l archive

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

This code:

local t = {}
for i = 1, 0x7fffffff do
t[i] = i

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.