1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-30 19:22:14 +00:00

Fix seg fault if popping from empty stack (L-system trees)

See: https://github.com/minetest/minetest/issues/1525

Background
Wuzzy2: If you attempt to spawn a L-system tree with minetest.spawn_tree, you can make Minetest crash if it is attempted to pop an empty stack.

ShadowNinja: This shouldn't cause a segmentation fault, but it should throw a Lua error

Commit Description
This commit throws a Lua error instead of causing a segmentation fault. The server will still "crash" but will include a Lua backtrace.

L-Systems fix randomness
Unless a random seed is provided (via Lua treedef) seed the PRNG with a different seed for each tree
Resolves: https://github.com/minetest/minetest/issues/1469

Fix l-system crash when treedef random_level not set by Lua
This commit is contained in:
Craig Robbins 2014-08-07 15:39:12 +10:00 committed by RealBadAngel
parent 996ea60642
commit f33d31693e
4 changed files with 45 additions and 10 deletions

View file

@ -118,14 +118,19 @@ void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
}
// L-System tree LUA spawner
void spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition)
treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition)
{
ServerMap *map = &env->getServerMap();
std::map<v3s16, MapBlock*> modified_blocks;
ManualMapVoxelManipulator vmanip(map);
v3s16 tree_blockp = getNodeBlockPos(p0);
treegen::error e;
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,3,1));
make_ltree (vmanip, p0, ndef, tree_definition);
e = make_ltree (vmanip, p0, ndef, tree_definition);
if (e != SUCCESS)
return e;
vmanip.blitBackAll(&modified_blocks);
// update lighting
@ -142,15 +147,25 @@ void spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDe
event.modified_blocks.insert(i->first);
}
map->dispatchEvent(&event);
return SUCCESS;
}
//L-System tree generator
void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef,
treegen::error make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef,
TreeDef tree_definition)
{
MapNode dirtnode(ndef->getId("mapgen_dirt"));
int seed;
if (tree_definition.explicit_seed)
{
seed = tree_definition.seed+14002;
}
else
{
seed = p0.X*2 + p0.Y*4 + p0.Z; // use the tree position to seed PRNG
}
PseudoRandom ps(seed);
PseudoRandom ps(tree_definition.seed+14002);
// chance of inserting abcd rules
double prop_a = 9;
double prop_b = 8;
@ -354,6 +369,8 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
stack_position.push(position);
break;
case ']':
if (stack_orientation.empty())
return UNBALANCED_BRACKETS;
rotation=stack_orientation.top();
stack_orientation.pop();
position=stack_position.top();
@ -393,6 +410,8 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
break;
}
}
return SUCCESS;
}
void tree_node_placement(ManualMapVoxelManipulator &vmanip, v3f p0,