1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

MetaDataRef: Make set_float preserve numbers exactly (#16090)

This commit is contained in:
Lars Müller 2025-05-02 21:27:00 +02:00 committed by GitHub
parent 6f3735281f
commit d96f5e1c76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 92 additions and 12 deletions

View file

@ -10,6 +10,7 @@
#include "map.h"
#include "server.h"
#include "util/basic_macros.h"
#include "util/string.h"
MetaDataRef *MetaDataRef::checkAnyMetadata(lua_State *L, int narg)
{
@ -166,9 +167,9 @@ int MetaDataRef::l_get_float(lua_State *L)
std::string str_;
const std::string &str = meta->getString(name, &str_);
// Convert with Lua, as is done in set_float.
lua_pushlstring(L, str.data(), str.size());
lua_pushnumber(L, lua_tonumber(L, -1));
// TODO this silently produces 0.0 if conversion fails, which is a footgun
f64 number = my_string_to_double(str).value_or(0.0);
lua_pushnumber(L, number);
return 1;
}
@ -179,12 +180,11 @@ int MetaDataRef::l_set_float(lua_State *L)
MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
luaL_checknumber(L, 3);
// Convert number to string with Lua as it gives good precision.
std::string str = readParam<std::string>(L, 3);
f64 number = luaL_checknumber(L, 3);
IMetadata *meta = ref->getmeta(true);
if (meta != NULL && meta->setString(name, str))
// Note: Do not use Lua's tostring for the conversion - it rounds.
if (meta != NULL && meta->setString(name, my_double_to_string(number)))
ref->reportMetadataChange(&name);
return 0;
}
@ -289,8 +289,11 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, IMetadata *meta)
while (lua_next(L, fieldstable) != 0) {
// key at index -2 and value at index -1
std::string name = readParam<std::string>(L, -2);
auto value = readParam<std::string_view>(L, -1);
meta->setString(name, value);
if (lua_type(L, -1) == LUA_TNUMBER) {
log_deprecated(L, "Passing `fields` with number values "
"is deprecated and may result in loss of precision.");
}
meta->setString(name, readParam<std::string_view>(L, -1));
lua_pop(L, 1); // Remove value, keep key for next iteration
}
lua_pop(L, 1);