Skip to content
Permalink
Browse files

Lua API: Log incorrect parameter types as error (#9954)

Incorrect parameter types are logged as errors, taking coercion into account.
This is a workaround to ensure mod compatibility.
Duplicate warnings are ignored per server instance.
  • Loading branch information
SmallJoker committed Jun 1, 2020
1 parent a08d18a commit 42a9b45c21ad407689950e3a4c90cb3894142260
Showing with 29 additions and 3 deletions.
  1. +29 −3 src/script/common/c_converter.cpp
@@ -28,6 +28,7 @@ extern "C" {
#include "common/c_converter.h"
#include "common/c_internal.h"
#include "constants.h"
#include <set>


#define CHECK_TYPE(index, name, type) { \
@@ -458,11 +459,36 @@ size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result

bool check_field_or_nil(lua_State *L, int index, int type, const char *fieldname)
{
if (lua_isnil(L, index))
static thread_local std::set<u64> warned_msgs;

int t = lua_type(L, index);
if (t == LUA_TNIL)
return false;

CHECK_TYPE(index, std::string("field \"") + fieldname + '"', type);
return true;
if (t == type)
return true;

// Check coercion types
if (type == LUA_TNUMBER) {
if (lua_isnumber(L, index))
return true;
} else if (type == LUA_TSTRING) {
if (lua_isstring(L, index))
return true;
}

// Types mismatch. Log unique line.
std::string backtrace = std::string("Invalid field ") + fieldname +
" (expected " + lua_typename(L, type) +
" got " + lua_typename(L, t) + ").\n" + script_get_backtrace(L);

u64 hash = murmur_hash_64_ua(backtrace.data(), backtrace.length(), 0xBADBABE);
if (warned_msgs.find(hash) == warned_msgs.end()) {
errorstream << backtrace << std::endl;
warned_msgs.insert(hash);
}

return false;
}

bool getstringfield(lua_State *L, int table,

0 comments on commit 42a9b45

Please sign in to comment.
You can’t perform that action at this time.