From a394aefd1a8a4e4fd49c50f068543a37884813cd Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 13 Sep 2022 22:41:18 +0200 Subject: [PATCH] Fix crash when cancelling automation scripts When cancelling an automation macro from the progress dialog, the dialog throws a UserCancelException. If the macro still runs to the end afterwards (instead of calling aegisub.cancel or causing an exception), the two return values are left on the stack. This causes assertion errors due to check_stack when those are enabled. --- src/auto4_lua.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp index 6c131902e..2044c3681 100644 --- a/src/auto4_lua.cpp +++ b/src/auto4_lua.cpp @@ -624,27 +624,33 @@ namespace { { bool failed = false; BackgroundScriptRunner bsr(parent, title); - bsr.Run([&](ProgressSink *ps) { - LuaProgressSink lps(L, ps, can_open_config); + try { + bsr.Run([&](ProgressSink *ps) { + LuaProgressSink lps(L, ps, can_open_config); - // Insert our error handler under the function to call - lua_pushcclosure(L, add_stack_trace, 0); - lua_insert(L, -nargs - 2); + // Insert our error handler under the function to call + lua_pushcclosure(L, add_stack_trace, 0); + lua_insert(L, -nargs - 2); - if (lua_pcall(L, nargs, nresults, -nargs - 2)) { - if (!lua_isnil(L, -1)) { - // if the call failed, log the error here - ps->Log("\n\nLua reported a runtime error:\n"); - ps->Log(get_string_or_default(L, -1)); + if (lua_pcall(L, nargs, nresults, -nargs - 2)) { + if (!lua_isnil(L, -1)) { + // if the call failed, log the error here + ps->Log("\n\nLua reported a runtime error:\n"); + ps->Log(get_string_or_default(L, -1)); + } + lua_pop(L, 2); + failed = true; } - lua_pop(L, 2); - failed = true; - } - else - lua_remove(L, -nresults - 1); + else + lua_remove(L, -nresults - 1); - lua_gc(L, LUA_GCCOLLECT, 0); - }); + lua_gc(L, LUA_GCCOLLECT, 0); + }); + } catch (agi::UserCancelException const&) { + if (!failed) + lua_pop(L, 2); + throw; + } if (failed) throw agi::UserCancelException("Script threw an error"); }