Merge pull request 'Fix potential crashes due to unregistered nodes.' (#2055) from fix-unregistered-nodes into master

Reviewed-on: MineClone2/MineClone2#2055
Reviewed-by: cora <cora@noreply.git.minetest.land>
This commit is contained in:
cora 2022-03-09 22:16:27 +00:00
commit dca653651c
15 changed files with 298 additions and 31 deletions

View File

@ -256,6 +256,8 @@ function minetest.handle_node_drops(pos, drops, digger)
local silk_touch_drop = false
local nodedef = minetest.registered_nodes[dug_node.name]
if not nodedef then return end
if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
if nodedef._mcl_shears_drop == true then
drops = { dug_node.name }

View File

@ -432,7 +432,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
-- Slow down or speed up
local acc = dir.y * -1.8
local friction = 0.4
local speed_mod = minetest.registered_nodes[minetest.get_node(pos).name]._rail_acceleration
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
local speed_mod = ndef and ndef._rail_acceleration
acc = acc - friction
@ -860,4 +861,4 @@ if has_mcl_wip then
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
end
end

View File

@ -1328,8 +1328,8 @@ local do_jump = function(self)
return false
end
if self.walk_chance == 0
or minetest.registered_items[nod.name].walkable then
local ndef = minetest.registered_nodes[nod.name]
if self.walk_chance == 0 or ndef and ndef.walkable then
if minetest.get_item_group(nod.name, "fence") == 0
and minetest.get_item_group(nod.name, "fence_gate") == 0

View File

@ -50,8 +50,10 @@ mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
table.remove(check_offsets, r)
-- Long story short, spawn on a platform
if minetest.registered_nodes[minetest.get_node(telepos).name].walkable == false and
minetest.registered_nodes[minetest.get_node(telepos_below).name].walkable == true then
local trynode = minetest.registered_nodes[minetest.get_node(telepos).name]
local trybelownode = minetest.registered_nodes[minetest.get_node(telepos_below).name]
if trynode and not trynode.walkable and
trybelownode and trybelownode.walkable then
-- Correct position found! Let's teleport.
self.object:set_pos(telepos)
return

View File

@ -189,9 +189,10 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
local v = vector.normalize(self.object:get_velocity())
local crashpos = vector.subtract(pos, v)
local crashnode = minetest.get_node(crashpos)
local cndef = minetest.registered_nodes[crashnode.name]
-- Set fire if node is air, or a replacable flammable node (e.g. a plant)
if crashnode.name == "air" or
(minetest.registered_nodes[crashnode.name].buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then
(cndef and cndef.buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then
minetest.set_node(crashpos, {name = mobs_mc.items.fire})
end
end

View File

@ -478,7 +478,8 @@ mobs:register_mob("mobs_mc:enderman", {
-- Selected node needs to have 3 nodes of free space above
for u=1, 3 do
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
if minetest.registered_nodes[node.name].walkable then
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.walkable then
node_ok = false
break
end
@ -512,7 +513,8 @@ mobs:register_mob("mobs_mc:enderman", {
node_ok = true
for u=1, 3 do
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
if minetest.registered_nodes[node.name].walkable then
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.walkable then
node_ok = false
break
end

View File

@ -16,7 +16,8 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
if not eject_speed then
eject_speed = 1
end
local mother_stuck = minetest.registered_nodes[minetest.get_node(pos).name].walkable
local mndef = minetest.registered_nodes[minetest.get_node(pos).name]
local mother_stuck = mndef and mndef.walkable
angle = math.random(0, math.pi*2)
local children = {}
for i=1,children_count do
@ -26,7 +27,8 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
-- If child would end up in a wall, use position of the "mother", unless
-- the "mother" was stuck as well
local speed_penalty = 1
if (not mother_stuck) and minetest.registered_nodes[minetest.get_node(newpos).name].walkable then
local cndef = minetest.registered_nodes[minetest.get_node(newpos).name]
if (not mother_stuck) and cndef and cndef.walkable then
newpos = pos
speed_penalty = 0.5
end

View File

@ -210,7 +210,8 @@ minetest.register_abm({
end
local posses = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }
for _, p in pairs(posses) do
if minetest.registered_nodes[minetest.get_node(vector.new(pos.x + p[1], pos.y, pos.z + p[2])).name].walkable then
local ndef = minetest.registered_nodes[minetest.get_node(vector.new(pos.x + p[1], pos.y, pos.z + p[2])).name]
if ndef and ndef.walkable then
local posy = pos.y
while minetest.get_node(vector.new(pos.x, posy, pos.z)).name == "mcl_core:cactus" do
local pos = vector.new(pos.x, posy, pos.z)
@ -841,7 +842,7 @@ minetest.register_abm({
-- If this was mycelium, uproot plant above
if n2.name == "mcl_core:mycelium" then
local tad = minetest.registered_nodes[minetest.get_node(above).name]
if tad.groups and tad.groups.non_mycelium_plant then
if tad and tad.groups and tad.groups.non_mycelium_plant then
minetest.dig_node(above)
end
end
@ -1333,7 +1334,7 @@ minetest.register_abm({
function mcl_core.supports_vines(nodename)
local def = minetest.registered_nodes[nodename]
-- Rules: 1) walkable 2) full cube
return def.walkable and
return def and def.walkable and
(def.node_box == nil or def.node_box.type == "regular") and
(def.collision_box == nil or def.collision_box.type == "regular")
end

View File

@ -134,10 +134,15 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Check floor and ceiling: Must be *completely* solid
local y_floor = y
local y_ceiling = y + dim.y + 1
if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
if not registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable
or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
end end end
if check then
for tx = x+1, x+dim.x do
for tz = z+1, z+dim.z do
local fdef = registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name]
local cdef = registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name]
if not fdef or not fdef.walkable or not cdef or not cdef.walkable then return false end
end
end
end
-- Check for air openings (2 stacked air at ground level) in wall positions
local openings_counter = 0
@ -287,7 +292,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
local name = get_node(p).name
if registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
local rn = registered_nodes[name]
if rn and rn.is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
-- Floor
if ty == y then
if pr:next(1,4) == 1 then

View File

@ -179,7 +179,7 @@ function mcl_structures.generate_igloo(pos, rotation, pr)
real_depth = real_depth + 1
local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z})
local def = minetest.registered_nodes[node.name]
if (not def) or (not def.walkable) or (def.liquidtype ~= "none") or (not def.is_ground_content) then
if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then
bpos.y = tpos.y-y+1
break
end

View File

@ -154,16 +154,16 @@ local function SetNodeIfCanBuild(pos, node, check_above, can_replace_rail)
local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name
local abovedef = minetest.registered_nodes[abovename]
if abovename == "unknown" or abovename == "ignore" or
(abovedef.groups and abovedef.groups.attached_node) or
(abovedef and abovedef.groups and abovedef.groups.attached_node) or
-- This is done because cobwebs are often fake liquids
(abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then
(abovedef and abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then
return false
end
end
local name = minetest.get_node(pos).name
local def = minetest.registered_nodes[name]
if name ~= "unknown" and name ~= "ignore" and
((def.is_ground_content and def.liquidtype == "none") or
((def and def.is_ground_content and def.liquidtype == "none") or
name == tsm_railcorridors.nodes.cobweb or
name == tsm_railcorridors.nodes.torch_wall or
name == tsm_railcorridors.nodes.torch_floor or
@ -192,7 +192,7 @@ end
local function IsGround(pos)
local nodename = minetest.get_node(pos).name
local nodedef = minetest.registered_nodes[nodename]
return nodename ~= "unknown" and nodename ~= "ignore" and nodedef.is_ground_content and nodedef.walkable and nodedef.liquidtype == "none"
return nodename ~= "unknown" and nodename ~= "ignore" and nodedef and nodedef.is_ground_content and nodedef.walkable and nodedef.liquidtype == "none"
end
-- Returns true if rails are allowed to be placed on top of this node
@ -200,7 +200,7 @@ local function IsRailSurface(pos)
local nodename = minetest.get_node(pos).name
local nodename_above = minetest.get_node({x=pos.x,y=pos.y+2,z=pos.z}).name
local nodedef = minetest.registered_nodes[nodename]
return nodename ~= "unknown" and nodename ~= "ignore" and nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodename_above ~= tsm_railcorridors.nodes.rail
return nodename ~= "unknown" and nodename ~= "ignore" and nodedef and nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodename_above ~= tsm_railcorridors.nodes.rail
end
-- Checks if the node is empty space which requires to be filled by a platform
@ -211,7 +211,7 @@ local function NeedsPlatform(pos)
local falling = minetest.get_item_group(node.name, "falling_node") == 1
return
-- Node can be replaced if ground content or rail
(node.name ~= "ignore" and node.name ~= "unknown" and nodedef.is_ground_content) and
(node.name ~= "ignore" and node.name ~= "unknown" and nodedef and nodedef.is_ground_content) and
-- Node needs platform if node below is not walkable.
-- Unless 2 nodes below there is dirt: This is a special case for the starter cube.
((nodedef.walkable == false and node2.name ~= tsm_railcorridors.nodes.dirt) or
@ -253,7 +253,7 @@ local function Cube(p, radius, node, replace_air_only, wood, post)
if yi == y_top then
local topnode = minetest.get_node({x=xi,y=yi+1,z=zi})
local topdef = minetest.registered_nodes[topnode.name]
if minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef.liquidtype == "none" then
if minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef and topdef.liquidtype == "none" then
ok = true
end
elseif column_last_attached and yi == column_last_attached - 1 then
@ -277,7 +277,7 @@ local function Cube(p, radius, node, replace_air_only, wood, post)
elseif wood and (xi == p.x or zi == p.z) and thisnode.name == wood then
local topnode = minetest.get_node({x=xi,y=yi+1,z=zi})
local topdef = minetest.registered_nodes[topnode.name]
if topdef.walkable and topnode.name ~= wood then
if topdef and topdef.walkable and topnode.name ~= wood then
minetest.set_node({x=xi,y=yi,z=zi}, node)
-- Check for torches around the wood and schedule them
-- for removal
@ -429,7 +429,7 @@ local function TryPlaceCobweb(pos, needs_check, side_vector)
local cpos = vector.add(pos, check_vectors[c])
local cname = minetest.get_node(cpos).name
local cdef = minetest.registered_nodes[cname]
if cname ~= "ignore" and cdef.walkable then
if cname ~= "ignore" and cdef and cdef.walkable then
check_passed = true
break
end
@ -523,12 +523,12 @@ local function WoodSupport(p, wood, post, torches, dir, torchdir)
local nodedef1 = minetest.registered_nodes[minetest.get_node(pos1).name]
local nodedef2 = minetest.registered_nodes[minetest.get_node(pos2).name]
if nodedef1.walkable then
if nodedef1 and nodedef1.walkable then
pos1.y = pos1.y + 1
end
SetNodeIfCanBuild(pos1, node, true)
if nodedef2.walkable then
if nodedef2 and nodedef2.walkable then
pos2.y = pos2.y + 1
end
SetNodeIfCanBuild(pos2, node, true)

16
mods/TODO.CORE Normal file
View File

@ -0,0 +1,16 @@
CORE/_mcl_autogroup/init.lua:
-> Enumerates entries of the registered_nodes table. Safe.
CORE/flowlib/init.lua:
-> All instances are checked before use.
CORE/mcl_explosions/init.lua:
-> Enumerates entries of the registered_nodes table. Safe.
CORE/walkover/init.lua:
-> Enumerates entries of the registered_nodes table. Safe.
CORE/mcl_util/init.lua:
-> All instances are checked before use.
- should use local.
- defines mcl_util.call_on_rightclick, but does not use it.

61
mods/TODO.ENTITIES Normal file
View File

@ -0,0 +1,61 @@
ENTITIES/mcl_boats/init.lua:
-> All instances are checked before use.
- one use in stray comment.
- should use local or should use mcl_util.call_on_rightclick.
ENTITIES/mcl_dripping/init.lua:
-> Only references one directly indexed entry. Safe.
ENTITIES/mcl_mobs/api.lua:
-> Uses node_ok() that checks and always returns valid nodes. Safe.
- line 1331 minetest.registered_items? Fixed
- should use locals.
ENTITIES/mcl_mobs/spawning.lua:
-> Only instances in commented out spawning code. Safe.
ENTITIES/mcl_mobs/mount.lua:
-> All instances shielded by node_ok(). Safe.
ENTITIES/mobs_mc/snowman.lua:
-> All instances checked. Safe.
- line 107 belowdef.nod_box == nil ?
ENTITIES/mobs_mc/2_throwing.lua:
-> All instances checked. Safe.
ENTITIES/mobs_mc/3_shared.lua:
-> Unchecked accesses. Fixed.
ENTITIES/mobs_mc/enderman.lua:
-> Unchecked accesses. Fixed.
- line 69: use indexed registered_nodes.
- line 259: weird but works.
- line 409 and onwards: restricted to takable_nodes.
ENTITIES/mobs_mc/blaze.lua:
-> Unchecked access. Fixed.
ENTITIES/mobs_mc/slime+magma_cube.lua:
-> Unchecked accesses. Fixed.
ENTITIES/mobs_mc/5_spawn_abm_check.lua:
-> Does not appear to be used at all.
- unchecked access. Unfixed.
ENTITIES/mcl_paintings/init.lua:
-> All instances checked. Safe.
ENTITIES/mcl_item_entity/init.lua:
-> Unchecked access. Fixed.
ENTITIES/mcl_falling_nodes/init.lua:
-> All instances checked. Safe.
- line 170: minetest.registered_nodes[self.node.name] is the same as bcd set on line 155
because of condition on line 164, therefore this access is safe. Sloppy code though.
ENTITIES/mcl_minecarts/init.lua:
-> Unchecked access. Fixed.
ENTITIES/mobs_mc_gameconfig/init.lua:
-> Only explicit indexing of registered_nodes. Safe

156
mods/TODO.ITEMS Normal file
View File

@ -0,0 +1,156 @@
ITEMS/mcl_portals/portal_nether.lua
-> not checked.
ITEMS/mcl_portals/portal_gateway.lua
-> not checked.
ITEMS/mcl_portals/portal_end.lua
-> not checked.
ITEMS/mcl_sponges/init.lua
-> not checked.
ITEMS/mcl_beds/api.lua
-> not checked.
ITEMS/mcl_beds/functions.lua
-> not checked.
ITEMS/mcl_torches/api.lua
-> not checked.
ITEMS/mcl_tools/init.lua
-> not checked.
ITEMS/mcl_ocean/seagrass.lua
-> not checked.
ITEMS/mcl_ocean/kelp.lua
-> not checked.
ITEMS/mcl_ocean/corals.lua
-> not checked.
ITEMS/mcl_ocean/sea_pickle.lua
-> not checked.
ITEMS/mcl_lanterns/init.lua
-> not checked.
ITEMS/mcl_stairs/api.lua
-> not checked.
ITEMS/mcl_stairs/cornerstair.lua
-> not checked.
ITEMS/mcl_dye/init.lua
-> not checked.
ITEMS/mcl_bows/crossbow.lua
-> not checked.
ITEMS/mcl_bows/bow.lua
-> not checked.
ITEMS/mcl_bows/rocket.lua
-> not checked.
ITEMS/mcl_bows/arrow.lua
-> not checked.
ITEMS/mcl_buckets/init.lua
-> not checked.
ITEMS/mcl_buckets/register.lua
-> not checked.
ITEMS/mcl_throwing/register.lua
-> not checked.
ITEMS/mcl_flowers/init.lua
-> not checked.
ITEMS/mcl_tnt/init.lua
-> not checked.
ITEMS/mcl_cocoas/init.lua
-> not checked.
ITEMS/xpanes/init.lua
-> not checked.
ITEMS/mcl_potions/tipped_arrow.lua
-> not checked.
ITEMS/mcl_potions/potions.lua
-> not checked.
ITEMS/mcl_potions/init.lua
-> not checked.
ITEMS/mcl_end/end_crystal.lua
-> not checked.
ITEMS/mcl_end/chorus_plant.lua
-> not checked.
ITEMS/mcl_walls/init.lua
-> not checked.
ITEMS/mcl_fishing/init.lua
-> not checked.
ITEMS/mcl_composters/init.lua
-> not checked.
ITEMS/mcl_heads/init.lua
-> not checked.
ITEMS/mclx_fences/init.lua
-> not checked.
ITEMS/mcl_mobspawners/init.lua
-> not checked.
ITEMS/mclx_stairs/init.lua
-> not checked.
ITEMS/mclx_core/init.lua
-> not checked.
ITEMS/mcl_core/nodes_base.lua
-> not checked.
ITEMS/mcl_core/nodes_misc.lua
-> not checked.
ITEMS/mcl_core/nodes_cactuscane.lua
-> not checked.
ITEMS/mcl_core/nodes_climb.lua
-> not checked.
ITEMS/mcl_core/craftitems.lua
-> not checked.
ITEMS/mcl_core/functions.lua
-> Unchecked accesses. Fixed.
ITEMS/mcl_fire/init.lua
-> not checked.
ITEMS/mcl_fire/fire_charge.lua
-> not checked.
ITEMS/mcl_fire/flint_and_steel.lua
-> not checked.
ITEMS/mcl_banners/init.lua
-> not checked.
ITEMS/mcl_farming/shared_functions.lua
-> not checked.
ITEMS/mcl_farming/hoes.lua
-> not checked.
ITEMS/mcl_farming/soil.lua
-> not checked.
ITEMS/mcl_signs/init.lua
-> not checked.
ITEMS/mcl_maps/init.lua
-> not checked.
ITEMS/screwdriver/init.lua
-> not checked.
ITEMS/mcl_nether/lava.lua
-> not checked.
ITEMS/mcl_nether/nether_wart.lua
-> not checked.
ITEMS/mcl_books/init.lua
-> not checked.
ITEMS/mcl_chests/init.lua
-> not checked.
ITEMS/mcl_hoppers/init.lua
-> not checked.
ITEMS/mcl_colorblocks/init.lua
-> not checked.
ITEMS/REDSTONE/mcl_dispensers/init.lua
-> not checked.
ITEMS/REDSTONE/mcl_droppers/init_new.lua
-> not checked.
ITEMS/REDSTONE/mcl_droppers/init.lua
-> not checked.
ITEMS/REDSTONE/mcl_comparators/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_pressureplates/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_walllever/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_button/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons/internal.lua
-> not checked.
ITEMS/REDSTONE/mesecons/util.lua
-> not checked.
ITEMS/REDSTONE/mesecons_mvps/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_wires/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_delayer/init.lua
-> not checked.
ITEMS/REDSTONE/mesecons_pistons/init.lua
-> not checked.
ITEMS/mcl_itemframes/init.lua
-> not checked.
ITEMS/mcl_doors/api_doors.lua
-> not checked.

17
mods/TODO.MAPGEN Normal file
View File

@ -0,0 +1,17 @@
MAPGEN/mcl_villages/buildings.lua
-> Only use is checked. Safe.
MAPGEN/mcl_villages/utils.lua
-> Only indexed uses. Safe.
MAPGEN/tsm_railcorridors/init.lua
-> Unchecked accesses. Fixed.
MAPGEN/mcl_structures/init.lua
-> Unchecked access. Fixed.
MAPGEN/mcl_dungeons/init.lua
-> Unchecked accesses. Fixed.
MAPGEN/mcl_mapgen_core/init.lua
-> All uses are checked. Safe.