Browse Source

Fix missing limit check for block y pos (#14320)

sfan5 2 months ago
parent
commit
9da1354f3a
2 changed files with 19 additions and 26 deletions
  1. 16 26
      src/map.cpp
  2. 3 0
      src/mapsector.cpp

+ 16 - 26
src/map.cpp

@@ -1506,12 +1506,11 @@ MapSector *ServerMap::createSector(v2s16 p2d)
 		Do not create over max mapgen limit
 	*/
 	if (blockpos_over_max_limit(v3s16(p2d.X, 0, p2d.Y)))
-		throw InvalidPositionException("createSector(): pos. over max mapgen limit");
+		throw InvalidPositionException("createSector(): pos over max mapgen limit");
 
 	/*
 		Generate blank sector
 	*/
-
 	sector = new MapSector(this, p2d, m_gamedef);
 
 	/*
@@ -1524,20 +1523,11 @@ MapSector *ServerMap::createSector(v2s16 p2d)
 
 MapBlock * ServerMap::createBlock(v3s16 p)
 {
-	/*
-		Do not create over max mapgen limit
-	*/
-	if (blockpos_over_max_limit(p))
-		throw InvalidPositionException("createBlock(): pos. over max mapgen limit");
-
 	v2s16 p2d(p.X, p.Z);
 	s16 block_y = p.Y;
+
 	/*
 		This will create or load a sector if not found in memory.
-		If block exists on disk, it will be loaded.
-
-		NOTE: On old save formats, this will be slow, as it generates
-		      lighting on blocks for them.
 	*/
 	MapSector *sector;
 	try {
@@ -1552,11 +1542,16 @@ MapBlock * ServerMap::createBlock(v3s16 p)
 	*/
 
 	MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
-	if (block) {
+	if (block)
 		return block;
-	}
+
 	// Create blank
-	block = sector->createBlankBlock(block_y);
+	try {
+		block = sector->createBlankBlock(block_y);
+	} catch (InvalidPositionException &e) {
+		infostream << "createBlock: createBlankBlock() failed" << std::endl;
+		throw e;
+	}
 
 	return block;
 }
@@ -1576,10 +1571,10 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
 	}
 
 	if (create_blank) {
-		MapSector *sector = createSector(v2s16(p.X, p.Z));
-		MapBlock *block = sector->createBlankBlock(p.Y);
-
-		return block;
+		try {
+			MapSector *sector = createSector(v2s16(p.X, p.Z));
+			return sector->createBlankBlock(p.Y);
+		} catch (InvalidPositionException &e) {}
 	}
 
 	return NULL;
@@ -2000,9 +1995,7 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
 		u8 flags = 0;
 		MapBlock *block;
 		v3s16 p(x,y,z);
-		std::map<v3s16, u8>::iterator n;
-		n = m_loaded_blocks.find(p);
-		if(n != m_loaded_blocks.end())
+		if (m_loaded_blocks.count(p) > 0)
 			continue;
 
 		bool block_data_inexistent = false;
@@ -2020,10 +2013,7 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
 		{
 
 			if (load_if_inexistent && !blockpos_over_max_limit(p)) {
-				ServerMap *svrmap = (ServerMap *)m_map;
-				block = svrmap->emergeBlock(p, false);
-				if (block == NULL)
-					block = svrmap->createBlock(p);
+				block = m_map->emergeBlock(p, true);
 				block->copyTo(*this);
 			} else {
 				flags |= VMANIP_BLOCK_DATA_INEXIST;

+ 3 - 0
src/mapsector.cpp

@@ -71,6 +71,9 @@ std::unique_ptr<MapBlock> MapSector::createBlankBlockNoInsert(s16 y)
 {
 	assert(getBlockBuffered(y) == nullptr); // Pre-condition
 
+	if (blockpos_over_max_limit(v3s16(0, y, 0)))
+		throw InvalidPositionException("createBlankBlockNoInsert(): pos over max mapgen limit");
+
 	v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
 
 	return std::make_unique<MapBlock>(blockpos_map, m_gamedef);