Skip to content

Commit

Permalink
HUD: Reject and warn on invalid stat types (minetest#11548)
Browse files Browse the repository at this point in the history
This comes into play on older servers which do not know the "stat" type.
Warnings are only logged once to avoid spam within globalstep callbacks
  • Loading branch information
SmallJoker committed Aug 21, 2021
1 parent a72d130 commit 0c1e960
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 44 deletions.
34 changes: 23 additions & 11 deletions src/network/clientpackethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,17 +1119,29 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)

*pkt >> server_id >> stat;

if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE ||
stat == HUD_STAT_ALIGN || stat == HUD_STAT_OFFSET)
*pkt >> v2fdata;
else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT || stat == HUD_STAT_TEXT2)
*pkt >> sdata;
else if (stat == HUD_STAT_WORLD_POS)
*pkt >> v3fdata;
else if (stat == HUD_STAT_SIZE)
*pkt >> v2s32data;
else
*pkt >> intdata;
// Keep in sync with:server.cpp -> SendHUDChange
switch ((HudElementStat)stat) {
case HUD_STAT_POS:
case HUD_STAT_SCALE:
case HUD_STAT_ALIGN:
case HUD_STAT_OFFSET:
*pkt >> v2fdata;
break;
case HUD_STAT_NAME:
case HUD_STAT_TEXT:
case HUD_STAT_TEXT2:
*pkt >> sdata;
break;
case HUD_STAT_WORLD_POS:
*pkt >> v3fdata;
break;
case HUD_STAT_SIZE:
*pkt >> v2s32data;
break;
default:
*pkt >> intdata;
break;
}

ClientEvent *event = new ClientEvent();
event->type = CE_HUDCHANGE;
Expand Down
19 changes: 11 additions & 8 deletions src/script/common/c_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1989,15 +1989,17 @@ void push_hud_element(lua_State *L, HudElement *elem)
lua_setfield(L, -2, "style");
}

HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
bool read_hud_change(lua_State *L, HudElementStat &stat, HudElement *elem, void **value)
{
HudElementStat stat = HUD_STAT_NUMBER;
std::string statstr;
if (lua_isstring(L, 3)) {
std::string statstr = lua_tostring(L, 3);
{
int statint;
statstr = lua_tostring(L, 3);
stat = string_to_enum(es_HudElementStat, statint, statstr) ?
(HudElementStat)statint : stat;
if (!string_to_enum(es_HudElementStat, statint, statstr)) {
script_log_unique(L, "Unknown HUD stat type: " + statstr, warningstream);
return false;
}

stat = (HudElementStat)statint;
}

switch (stat) {
Expand Down Expand Up @@ -2060,7 +2062,8 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
*value = &elem->style;
break;
}
return stat;

return true;
}

/******************************************************************************/
Expand Down
10 changes: 5 additions & 5 deletions src/script/common/c_content.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,12 @@ void read_json_value (lua_State *L, Json::Value &root,
void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm =
false, bool hitpoint = false);

void push_objectRef (lua_State *L, const u16 id);
void push_objectRef (lua_State *L, const u16 id);

void read_hud_element (lua_State *L, HudElement *elem);
void read_hud_element (lua_State *L, HudElement *elem);

void push_hud_element (lua_State *L, HudElement *elem);
void push_hud_element (lua_State *L, HudElement *elem);

HudElementStat read_hud_change (lua_State *L, HudElement *elem, void **value);
bool read_hud_change (lua_State *L, HudElementStat &stat, HudElement *elem, void **value);

void push_collision_move_result(lua_State *L, const collisionMoveResult &res);
void push_collision_move_result(lua_State *L, const collisionMoveResult &res);
48 changes: 35 additions & 13 deletions src/script/common/c_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/

#include "common/c_internal.h"
#include "util/numeric.h"
#include "debug.h"
#include "log.h"
#include "porting.h"
#include "settings.h"
#include <algorithm> // std::find

std::string script_get_backtrace(lua_State *L)
{
Expand Down Expand Up @@ -135,24 +137,35 @@ void script_run_callbacks_f(lua_State *L, int nargs,
lua_remove(L, error_handler);
}

static void script_log(lua_State *L, const std::string &message,
std::ostream &log_to, bool do_error, int stack_depth)
static void script_log_add_source(lua_State *L, std::string &message, int stack_depth)
{
lua_Debug ar;

log_to << message << " ";
if (lua_getstack(L, stack_depth, &ar)) {
FATAL_ERROR_IF(!lua_getinfo(L, "Sl", &ar), "lua_getinfo() failed");
log_to << "(at " << ar.short_src << ":" << ar.currentline << ")";
message.append(" (at " + std::string(ar.short_src) + ":"
+ std::to_string(ar.currentline) + ")");
} else {
log_to << "(at ?:?)";
message.append(" (at ?:?)");
}
log_to << std::endl;
}

if (do_error)
script_error(L, LUA_ERRRUN, NULL, NULL);
else
infostream << script_get_backtrace(L) << std::endl;
bool script_log_unique(lua_State *L, std::string message, std::ostream &log_to,
int stack_depth)
{
thread_local std::vector<u64> logged_messages;

script_log_add_source(L, message, stack_depth);
u64 hash = murmur_hash_64_ua(message.data(), message.length(), 0xBADBABE);

if (std::find(logged_messages.begin(), logged_messages.end(), hash)
== logged_messages.end()) {

logged_messages.emplace_back(hash);
log_to << message << std::endl;
return true;
}
return false;
}

DeprecatedHandlingMode get_deprecated_handling_mode()
Expand All @@ -174,9 +187,18 @@ DeprecatedHandlingMode get_deprecated_handling_mode()
return ret;
}

void log_deprecated(lua_State *L, const std::string &message, int stack_depth)
void log_deprecated(lua_State *L, std::string message, int stack_depth)
{
DeprecatedHandlingMode mode = get_deprecated_handling_mode();
if (mode != DeprecatedHandlingMode::Ignore)
script_log(L, message, warningstream, mode == DeprecatedHandlingMode::Error, stack_depth);
if (mode == DeprecatedHandlingMode::Ignore)
return;

script_log_add_source(L, message, stack_depth);
warningstream << message << std::endl;

if (mode == DeprecatedHandlingMode::Error)
script_error(L, LUA_ERRRUN, NULL, NULL);
else
infostream << script_get_backtrace(L) << std::endl;
}

6 changes: 4 additions & 2 deletions src/script/common/c_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ void script_error(lua_State *L, int pcall_result, const char *mod, const char *f
void script_run_callbacks_f(lua_State *L, int nargs,
RunCallbacksMode mode, const char *fxn);

bool script_log_unique(lua_State *L, std::string message, std::ostream &log_to,
int stack_depth = 1);

enum class DeprecatedHandlingMode {
Ignore,
Log,
Expand All @@ -134,5 +137,4 @@ DeprecatedHandlingMode get_deprecated_handling_mode();
* @param message The deprecation method
* @param stack_depth How far on the stack to the first user function (ie: not builtin or core)
*/
void log_deprecated(lua_State *L, const std::string &message,
int stack_depth=1);
void log_deprecated(lua_State *L, std::string message, int stack_depth = 1);
5 changes: 3 additions & 2 deletions src/script/lua_api/l_localplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,11 @@ int LuaLocalPlayer::l_hud_change(lua_State *L)
if (!element)
return 0;

HudElementStat stat;
void *unused;
read_hud_change(L, element, &unused);
bool ok = read_hud_change(L, stat, element, &unused);

lua_pushboolean(L, true);
lua_pushboolean(L, ok);
return 1;
}

Expand Down
8 changes: 5 additions & 3 deletions src/script/lua_api/l_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1555,12 +1555,14 @@ int ObjectRef::l_hud_change(lua_State *L)
if (elem == nullptr)
return 0;

HudElementStat stat;
void *value = nullptr;
HudElementStat stat = read_hud_change(L, elem, &value);
bool ok = read_hud_change(L, stat, elem, &value);

getServer(L)->hudChange(player, id, stat, value);
if (ok)
getServer(L)->hudChange(player, id, stat, value);

lua_pushboolean(L, true);
lua_pushboolean(L, ok);
return 1;
}

Expand Down

0 comments on commit 0c1e960

Please sign in to comment.