Test and fix swapping clients

The code in luaA_client_swap() is incorrect, because
luaA_object_emit_signal() already pops the arguments to the signal.
Still, the code here tried to remove the arguments from the Lua stack
again, thereby corrupting the stack (removing more items than there are
in the stack).

Normally, popping more things from the stack than it has entries
silently corrupts the Lua stack. Apparently this doesn't necessarily
cause any immediate issues, because this code has been broken since nine
months and no one noticed. This mistakes was introduced in commit
55190646.

This issue was only noticed by accident. Thus, this commit also adds a
small integration test that exercises this bug. This test catches the
issue, but only on Travis, because there we are building our own version
of Lua 5.3 and that one has assertions enabled.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-10-29 09:34:45 +02:00
parent d71bb665d1
commit c218b1da72
2 changed files with 33 additions and 2 deletions

View File

@ -2343,13 +2343,11 @@ luaA_client_swap(lua_State *L)
luaA_object_push(L, swap); luaA_object_push(L, swap);
lua_pushboolean(L, true); lua_pushboolean(L, true);
luaA_object_emit_signal(L, -4, "swapped", 2); luaA_object_emit_signal(L, -4, "swapped", 2);
lua_pop(L, 2);
luaA_object_push(L, swap); luaA_object_push(L, swap);
luaA_object_push(L, c); luaA_object_push(L, c);
lua_pushboolean(L, false); lua_pushboolean(L, false);
luaA_object_emit_signal(L, -3, "swapped", 2); luaA_object_emit_signal(L, -3, "swapped", 2);
lua_pop(L, 3);
} }
return 0; return 0;

View File

@ -0,0 +1,33 @@
-- Test if client's c:swap() corrupts the Lua stack
local runner = require("_runner")
local test_client = require("_client")
runner.run_steps({
-- Spawn two clients
function(count)
if count == 1 then
test_client()
test_client()
end
if #client.get() >= 2 then
return true
end
end,
-- Swap them
function()
assert(#client.get() == 2, #client.get())
local c1 = client.get()[1]
local c2 = client.get()[2]
c2:swap(c1)
c1:swap(c2)
c1:swap(c2)
c1:swap(c2)
c2:swap(c1)
return true
end,
})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80