From 3cc45fd8adf4213bfd979273a094b33fecb6c7db Mon Sep 17 00:00:00 2001 From: kwolekr 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 de9b5aba..fe7ac8dd 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 > 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 > 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;