diff options
author | rubenwardy <rw@rubenwardy.com> | 2019-03-12 07:56:56 +0000 |
---|---|---|
committer | Loïc Blot <nerzhul@users.noreply.github.com> | 2019-03-12 08:56:56 +0100 |
commit | 1e3e4fb6492832048b484ffe784613a16713f1d2 (patch) | |
tree | 672f8699f84afba9bd238bd5a0173e175d1ab260 /src | |
parent | 3b25b807f33bff885bd840ec0dc9e2d95b392f81 (diff) | |
download | minetest-1e3e4fb6492832048b484ffe784613a16713f1d2.tar.gz minetest-1e3e4fb6492832048b484ffe784613a16713f1d2.tar.bz2 minetest-1e3e4fb6492832048b484ffe784613a16713f1d2.zip |
HPChange Reason: Fix push after free, and type being overwritten (#8359)
* HPChange Reason: Fix push after free, and type being overwritten
Fixes #8227 and #8344
Diffstat (limited to 'src')
-rw-r--r-- | src/content_sao.h | 5 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.cpp | 14 | ||||
-rw-r--r-- | src/script/lua_api/l_object.cpp | 3 |
3 files changed, 17 insertions, 5 deletions
diff --git a/src/content_sao.h b/src/content_sao.h index 14f959e30..f54bc16c2 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -405,6 +405,11 @@ struct PlayerHPChangeReason { bool from_mod = false; int lua_reference = -1; + inline bool hasLuaReference() const + { + return lua_reference >= 0; + } + bool setTypeFromString(const std::string &typestr) { if (typestr == "set_hp") diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index bf89f748c..a8ed902dd 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -384,14 +384,18 @@ void ScriptApiBase::objectrefGetOrCreate(lua_State *L, void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason) { - if (reason.lua_reference >= 0) { + if (reason.hasLuaReference()) lua_rawgeti(L, LUA_REGISTRYINDEX, reason.lua_reference); - luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference); - } else + else lua_newtable(L); - lua_pushstring(L, reason.getTypeAsString().c_str()); - lua_setfield(L, -2, "type"); + lua_getfield(L, -1, "type"); + bool has_type = (bool)lua_isstring(L, -1); + lua_pop(L, 1); + if (!has_type) { + lua_pushstring(L, reason.getTypeAsString().c_str()); + lua_setfield(L, -2, "type"); + } lua_pushstring(L, reason.from_mod ? "mod" : "engine"); lua_setfield(L, -2, "from"); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 9edb2f4f8..b3ed39c7c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -257,6 +257,9 @@ int ObjectRef::l_set_hp(lua_State *L) if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason); + if (reason.hasLuaReference()) + luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference); + // Return return 0; } |