From 3fa48281b00ccf0a7ba76b89b3247dda59965075 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 20 Mar 2014 13:58:58 -0700 Subject: [PATCH] Add an error check for trying to interact with expired subtitles objects --- src/auto4_lua.h | 2 +- src/auto4_lua_assfile.cpp | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/auto4_lua.h b/src/auto4_lua.h index 6a5273d3b..9695c3ad9 100644 --- a/src/auto4_lua.h +++ b/src/auto4_lua.h @@ -119,7 +119,7 @@ namespace Automation4 { // LuaAssFile can only be deleted by the reference count hitting zero ~LuaAssFile(); public: - static LuaAssFile *GetObjPointer(lua_State *L, int idx); + static LuaAssFile *GetObjPointer(lua_State *L, int idx, bool allow_expired); /// makes a Lua representation of AssEntry and places on the top of the stack void AssEntryToLua(lua_State *L, size_t idx); diff --git a/src/auto4_lua_assfile.cpp b/src/auto4_lua_assfile.cpp index e83f929aa..fc12ab8eb 100644 --- a/src/auto4_lua_assfile.cpp +++ b/src/auto4_lua_assfile.cpp @@ -103,13 +103,13 @@ namespace { template int closure_wrapper(lua_State *L) { - return (LuaAssFile::GetObjPointer(L, lua_upvalueindex(1))->*closure)(L); + return (LuaAssFile::GetObjPointer(L, lua_upvalueindex(1), false)->*closure)(L); } - template + template int closure_wrapper_v(lua_State *L) { - (LuaAssFile::GetObjPointer(L, lua_upvalueindex(1))->*closure)(L); + (LuaAssFile::GetObjPointer(L, lua_upvalueindex(1), allow_expired)->*closure)(L); return 0; } @@ -326,13 +326,13 @@ namespace Automation4 { lua_pushvalue(L, 1); if (strcmp(idx, "delete") == 0) - lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectDelete>, 1); + lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectDelete, false>, 1); else if (strcmp(idx, "deleterange") == 0) - lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectDeleteRange>, 1); + lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectDeleteRange, false>, 1); else if (strcmp(idx, "insert") == 0) - lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectInsert>, 1); + lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectInsert, false>, 1); else if (strcmp(idx, "append") == 0) - lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectAppend>, 1); + lua_pushcclosure(L, closure_wrapper_v<&LuaAssFile::ObjectAppend, false>, 1); else { // idiot lua_pop(L, 1); @@ -634,11 +634,14 @@ namespace Automation4 { } } - LuaAssFile *LuaAssFile::GetObjPointer(lua_State *L, int idx) + LuaAssFile *LuaAssFile::GetObjPointer(lua_State *L, int idx, bool allow_expired) { assert(lua_type(L, idx) == LUA_TUSERDATA); - void *ud = lua_touserdata(L, idx); - return *((LuaAssFile**)ud); + auto ud = lua_touserdata(L, idx); + auto laf = *static_cast(ud); + if (!allow_expired && laf->references < 2) + luaL_error(L, "Subtitles object is no longer valid"); + return laf; } std::vector LuaAssFile::ProcessingComplete(wxString const& undo_description) @@ -705,9 +708,9 @@ namespace Automation4 { // make the metatable lua_newtable(L); set_field(L, "__index", closure_wrapper<&LuaAssFile::ObjectIndexRead>); - set_field(L, "__newindex", closure_wrapper_v<&LuaAssFile::ObjectIndexWrite>); + set_field(L, "__newindex", closure_wrapper_v<&LuaAssFile::ObjectIndexWrite, false>); set_field(L, "__len", closure_wrapper<&LuaAssFile::ObjectGetLen>); - set_field(L, "__gc", closure_wrapper_v<&LuaAssFile::ObjectGarbageCollect>); + set_field(L, "__gc", closure_wrapper_v<&LuaAssFile::ObjectGarbageCollect, true>); set_field(L, "__ipairs", closure_wrapper<&LuaAssFile::ObjectIPairs>); lua_setmetatable(L, -2); @@ -716,7 +719,7 @@ namespace Automation4 { lua_getglobal(L, "aegisub"); set_field(L, "parse_karaoke_data", closure_wrapper<&LuaAssFile::LuaParseKaraokeData>); - set_field(L, "set_undo_point", closure_wrapper_v<&LuaAssFile::LuaSetUndoPoint>); + set_field(L, "set_undo_point", closure_wrapper_v<&LuaAssFile::LuaSetUndoPoint, false>); lua_pop(L, 1); // pop "aegisub" table