Skip to content

Commit

Permalink
HPChange Reason: Fix push after free, and type being overwritten (#8359)
Browse files Browse the repository at this point in the history
* HPChange Reason: Fix push after free, and type being overwritten

Fixes #8227 and #8344
  • Loading branch information
rubenwardy authored and nerzhul committed Mar 12, 2019
1 parent 3b25b80 commit 1e3e4fb
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/content_sao.h
Expand Up @@ -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")
Expand Down
14 changes: 9 additions & 5 deletions src/script/cpp_api/s_base.cpp
Expand Up @@ -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");
Expand Down
3 changes: 3 additions & 0 deletions src/script/lua_api/l_object.cpp
Expand Up @@ -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;
}
Expand Down

0 comments on commit 1e3e4fb

Please sign in to comment.