summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmallJoker <SmallJoker@users.noreply.github.com>2020-06-01 19:02:15 +0200
committerGitHub <noreply@github.com>2020-06-01 19:02:15 +0200
commit42a9b45c21ad407689950e3a4c90cb3894142260 (patch)
tree703f7ae0f257c61bbb86134ea5a44ac92d71ba2c
parenta08d18acad345363780f5286300d65b39ea9c9f9 (diff)
downloadminetest-42a9b45c21ad407689950e3a4c90cb3894142260.tar.gz
minetest-42a9b45c21ad407689950e3a4c90cb3894142260.tar.bz2
minetest-42a9b45c21ad407689950e3a4c90cb3894142260.zip
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.
-rw-r--r--src/script/common/c_converter.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp
index 279d8b1a5..de0cdfbf4 100644
--- a/src/script/common/c_converter.cpp
+++ b/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,