From 33087897fdb2ac2bd07700356a8edfa33d5a9ec6 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Tue, 14 Dec 2021 14:06:31 +0100 Subject: Fix minetest.find_nodes_in_area() coord clamping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, minetest.find_nodes_in_area() was affected by a signed integer overflow, which was fixed by clamping the area in which the function works to MAX_MAP_GENERATION_LIMIT & -MAX_MAP_GENERATION_LIMIT. The problem with that approach is that nodes can exist and even be generated past MAX_MAP_GENERATION_LIMIT in vanilla Minetest – which, despite the name, does not specify exactly where the map generator stops working. Therefore, the bug fix created an unknown amount of other bugs near the map border. At minimum, those bugs affect the outer mapblocks, where nodes past MAX_MAP_GENERATION_LIMIT can be generated. Ironically, the first thing broken by the faulty bug fix was a test case belonging to a workaround that prevents minetest.find_nodes_in_area() being called with coordinates out of s16 bounds in the Mineclonia game, thus avoiding signed integer overflow. Using INT16_MIN+1 & INT16_MAX-1 makes minetest.find_nodes_in_area() work for all coordinates that worked before the faulty fix, avoiding a situation where Minetest can place a node in the map, but then not find it afterwards using minetest_find_nodes_in_area(). --- src/script/lua_api/l_env.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 18ee3a521..ccb18d992 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -888,8 +888,9 @@ static void checkArea(v3s16 &minp, v3s16 &maxp) throw LuaError("Area volume exceeds allowed value of 4096000"); } - // Clamp to map range to avoid problems -#define CLAMP(arg) core::clamp(arg, (s16)-MAX_MAP_GENERATION_LIMIT, (s16)MAX_MAP_GENERATION_LIMIT) + // Clamp to almost s16 range to avoid problems + // Clamping to exactly s16 range hangs Minetest +#define CLAMP(arg) core::clamp(arg, (s16)(INT16_MIN+1), (s16)(INT16_MAX-1)) minp = v3s16(CLAMP(minp.X), CLAMP(minp.Y), CLAMP(minp.Z)); maxp = v3s16(CLAMP(maxp.X), CLAMP(maxp.Y), CLAMP(maxp.Z)); #undef CLAMP -- cgit v1.2.3