aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubenwardy <rw@rubenwardy.com>2019-03-12 07:56:56 +0000
committerLoïc Blot <nerzhul@users.noreply.github.com>2019-03-12 08:56:56 +0100
commit1e3e4fb6492832048b484ffe784613a16713f1d2 (patch)
tree672f8699f84afba9bd238bd5a0173e175d1ab260 /src
parent3b25b807f33bff885bd840ec0dc9e2d95b392f81 (diff)
downloadminetest-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.h5
-rw-r--r--src/script/cpp_api/s_base.cpp14
-rw-r--r--src/script/lua_api/l_object.cpp3
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;
}