From 3cc45fd8adf4213bfd979273a094b33fecb6c7db Mon Sep 17 00:00:00 2001
From: kwolekr <kwolekr@minetest.net>
Date: Sun, 8 Dec 2013 01:37:41 -0500
Subject: [PATCH] Fix leak and possible segfault in minetest.set_mapgen_params

---
 src/script/lua_api/l_mapgen.cpp | 82 +++++++++++++++++----------------
 1 file changed, 42 insertions(+), 40 deletions(-)

diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index de9b5aba7..fe7ac8dd6 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -81,45 +81,45 @@ struct EnumString ModApiMapgen::es_Rotation[] =
 int ModApiMapgen::l_get_mapgen_object(lua_State *L)
 {
 	const char *mgobjstr = lua_tostring(L, 1);
-	
+
 	int mgobjint;
 	if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
 		return 0;
-		
+
 	enum MapgenObject mgobj = (MapgenObject)mgobjint;
 
 	EmergeManager *emerge = getServer(L)->getEmergeManager();
 	Mapgen *mg = emerge->getCurrentMapgen();
 	if (!mg)
 		return 0;
-	
+
 	size_t maplen = mg->csize.X * mg->csize.Z;
-	
+
 	int nargs = 1;
-	
+
 	switch (mgobj) {
 		case MGOBJ_VMANIP: {
 			ManualMapVoxelManipulator *vm = mg->vm;
-			
+
 			// VoxelManip object
 			LuaVoxelManip *o = new LuaVoxelManip(vm, true);
 			*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
 			luaL_getmetatable(L, "VoxelManip");
 			lua_setmetatable(L, -2);
-			
+
 			// emerged min pos
 			push_v3s16(L, vm->m_area.MinEdge);
 
 			// emerged max pos
 			push_v3s16(L, vm->m_area.MaxEdge);
-			
+
 			nargs = 3;
-			
+
 			break; }
 		case MGOBJ_HEIGHTMAP: {
 			if (!mg->heightmap)
 				return 0;
-			
+
 			lua_newtable(L);
 			for (size_t i = 0; i != maplen; i++) {
 				lua_pushinteger(L, mg->heightmap[i]);
@@ -129,7 +129,7 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
 		case MGOBJ_BIOMEMAP: {
 			if (!mg->biomemap)
 				return 0;
-			
+
 			lua_newtable(L);
 			for (size_t i = 0; i != maplen; i++) {
 				lua_pushinteger(L, mg->biomemap[i]);
@@ -140,14 +140,14 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
 		case MGOBJ_HUMIDMAP:
 			if (strcmp(emerge->params->mg_name.c_str(), "v7"))
 				return 0;
-			
+
 			MapgenV7 *mgv7 = (MapgenV7 *)mg;
 
-			float *arr = (mgobj == MGOBJ_HEATMAP) ? 
+			float *arr = (mgobj == MGOBJ_HEATMAP) ?
 				mgv7->noise_heat->result : mgv7->noise_humidity->result;
 			if (!arr)
 				return 0;
-			
+
 			lua_newtable(L);
 			for (size_t i = 0; i != maplen; i++) {
 				lua_pushnumber(L, arr[i]);
@@ -155,7 +155,7 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
 			}
 			break; }
 	}
-	
+
 	return nargs;
 }
 
@@ -167,25 +167,25 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
 		return 0;
 
 	EmergeManager *emerge = getServer(L)->getEmergeManager();
-	if (emerge->mapgen.size())
+	if (!emerge || emerge->mapgen.size())
 		return 0;
-	
+
 	MapgenParams *oparams = new MapgenParams;
 	u32 paramsmodified = 0;
 	u32 flagmask = 0;
-	
+
 	lua_getfield(L, 1, "mgname");
 	if (lua_isstring(L, -1)) {
 		oparams->mg_name = std::string(lua_tostring(L, -1));
 		paramsmodified |= MGPARAMS_SET_MGNAME;
 	}
-	
+
 	lua_getfield(L, 1, "seed");
 	if (lua_isnumber(L, -1)) {
 		oparams->seed = lua_tointeger(L, -1);
 		paramsmodified |= MGPARAMS_SET_SEED;
 	}
-	
+
 	lua_getfield(L, 1, "water_level");
 	if (lua_isnumber(L, -1)) {
 		oparams->water_level = lua_tointeger(L, -1);
@@ -197,18 +197,20 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
 		std::string flagstr = std::string(lua_tostring(L, -1));
 		oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
 		paramsmodified |= MGPARAMS_SET_FLAGS;
-	
+
 		lua_getfield(L, 1, "flagmask");
 		if (lua_isstring(L, -1)) {
 			flagstr = std::string(lua_tostring(L, -1));
 			flagmask = readFlagString(flagstr, flagdesc_mapgen);
 		}
 	}
-	
+
+	delete emerge->luaoverride_params;
+
 	emerge->luaoverride_params          = oparams;
 	emerge->luaoverride_params_modified = paramsmodified;
 	emerge->luaoverride_flagmask        = flagmask;
-	
+
 	return 0;
 }
 
@@ -240,7 +242,7 @@ int ModApiMapgen::l_register_biome(lua_State *L)
 												"air");
 	b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
 												"mapgen_water_source");
-	
+
 	b->depth_top      = getintfield_default(L, index, "depth_top",    1);
 	b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
 	b->height_min     = getintfield_default(L, index, "height_min",   0);
@@ -254,7 +256,7 @@ int ModApiMapgen::l_register_biome(lua_State *L)
 	b->c_water      = CONTENT_IGNORE;
 	b->c_dust       = CONTENT_IGNORE;
 	b->c_dust_water = CONTENT_IGNORE;
-	
+
 	verbosestream << "register_biome: " << b->name << std::endl;
 	bmgr->addBiome(b);
 
@@ -277,7 +279,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 			"decoration placement type";
 		return 0;
 	}
-	
+
 	Decoration *deco = createDecoration(decotype);
 	if (!deco) {
 		errorstream << "register_decoration: decoration placement type "
@@ -295,11 +297,11 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 		delete deco;
 		return 0;
 	}
-	
+
 	lua_getfield(L, index, "noise_params");
 	deco->np = read_noiseparams(L, -1);
 	lua_pop(L, 1);
-	
+
 	lua_getfield(L, index, "biomes");
 	if (lua_istable(L, -1)) {
 		lua_pushnil(L);
@@ -313,7 +315,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 		}
 		lua_pop(L, 1);
 	}
-	
+
 	switch (decotype) {
 		case DECO_SIMPLE: {
 			DecoSimple *dsimple = (DecoSimple *)deco;
@@ -323,7 +325,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 			dsimple->deco_height     = getintfield_default(L, index, "height", 1);
 			dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
 			dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);
-			
+
 			lua_getfield(L, index, "decoration");
 			if (lua_istable(L, -1)) {
 				lua_pushnil(L);
@@ -340,7 +342,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 				dsimple->deco_name = std::string("air");
 			}
 			lua_pop(L, 1);
-			
+
 			if (dsimple->deco_height <= 0) {
 				errorstream << "register_decoration: simple decoration height"
 					" must be greater than 0" << std::endl;
@@ -380,7 +382,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 				return 0;
 			}
 			lua_pop(L, -1);
-			
+
 			if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
 				errorstream << "register_decoration: failed to load schematic file '"
 					<< dschem->filename << "'" << std::endl;
@@ -390,7 +392,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
 			break; }
 		case DECO_LSYSTEM: {
 			//DecoLSystem *decolsystem = (DecoLSystem *)deco;
-		
+
 			break; }
 	}
 
@@ -474,7 +476,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
 	v3s16 p1 = read_v3s16(L, 1);
 	v3s16 p2 = read_v3s16(L, 2);
 	sortBoxVerticies(p1, p2);
-	
+
 	std::vector<std::pair<v3s16, u8> > prob_list;
 	if (lua_istable(L, 3)) {
 		lua_pushnil(L);
@@ -483,7 +485,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
 				lua_getfield(L, -1, "pos");
 				v3s16 pos = read_v3s16(L, -1);
 				lua_pop(L, 1);
-				
+
 				u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
 				prob_list.push_back(std::make_pair(pos, prob));
 			}
@@ -491,7 +493,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
 			lua_pop(L, 1);
 		}
 	}
-	
+
 	std::vector<std::pair<s16, u8> > slice_prob_list;
 	if (lua_istable(L, 5)) {
 		lua_pushnil(L);
@@ -516,7 +518,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
 	}
 
 	dschem.applyProbabilities(p1, &prob_list, &slice_prob_list);
-	
+
 	dschem.saveSchematicFile(ndef);
 	actionstream << "create_schematic: saved schematic file '"
 		<< dschem.filename << "'." << std::endl;
@@ -536,11 +538,11 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
 	v3s16 p = read_v3s16(L, 1);
 	if (!read_schematic(L, 2, &dschem, getServer(L)))
 		return 0;
-		
+
 	int rot = ROTATE_0;
 	if (lua_isstring(L, 3))
 		string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3)));
-		
+
 	dschem.rotation = (Rotation)rot;
 
 	if (lua_istable(L, 4)) {
@@ -568,7 +570,7 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
 		}
 		dschem.resolveNodeNames(ndef);
 	}
-	
+
 	dschem.placeStructure(map, p);
 
 	return 1;
-- 
GitLab