浏览代码

Fix crash on exporting maps for translation

Ivan Savenko 1 年之前
父节点
当前提交
638bc174c3

+ 10 - 3
client/ClientCommandManager.cpp

@@ -254,9 +254,16 @@ void ClientCommandManager::handleTranslateMapsCommand()
 	logGlobal->info("Loading campaigns for export");
 	for (auto const & campaignName : campaignList)
 	{
-		loadedCampaigns.push_back(CampaignHandler::getCampaign(campaignName.getName()));
-		for (auto const & part : loadedCampaigns.back()->allScenarios())
-			loadedCampaigns.back()->getMap(part, nullptr);
+		try
+		{
+			loadedCampaigns.push_back(CampaignHandler::getCampaign(campaignName.getName()));
+			for (auto const & part : loadedCampaigns.back()->allScenarios())
+				loadedCampaigns.back()->getMap(part, nullptr);
+		}
+		catch(std::exception & e)
+		{
+			logGlobal->warn("Campaign %s is invalid. Message: %s", campaignName.getName(), e.what());
+		}
 	}
 
 	std::map<std::string, std::map<std::string, std::string>> textsByMod;

+ 3 - 0
lib/filesystem/CCompressedStream.cpp

@@ -136,6 +136,9 @@ si64 CCompressedStream::readMore(ui8 *data, si64 size)
 	{
 		if (inflateState->avail_in == 0)
 		{
+			if (gzipStream == nullptr)
+				throw std::runtime_error("Potentially truncated gzip file");
+
 			//inflate ran out of available data or was not initialized yet
 			// get new input data and update state accordingly
 			si64 availSize = gzipStream->read(compressedBuffer.data(), compressedBuffer.size());

+ 3 - 0
lib/mapping/MapFormatH3M.cpp

@@ -208,6 +208,9 @@ void CMapLoaderH3M::readHeader()
 
 	// optimization - load mappings only once to avoid slow parsing of map headers for map list
 	static const std::map<EMapFormat, MapIdentifiersH3M> identifierMappers = generateMappings();
+	if (!identifierMappers.count(mapHeader->version))
+		throw std::runtime_error("Unsupported map format! Format ID " + std::to_string(static_cast<int>(mapHeader->version)));
+
 	const MapIdentifiersH3M & identifierMapper = identifierMappers.at(mapHeader->version);
 
 	reader->setIdentifierRemapper(identifierMapper);

+ 0 - 2
lib/mapping/MapFormatJson.cpp

@@ -1014,8 +1014,6 @@ void CMapLoaderJson::readTerrain()
 		const JsonNode underground = getFromArchive(TERRAIN_FILE_NAMES[1]);
 		readTerrainLevel(underground, 1);
 	}
-
-	map->calculateWaterContent();
 }
 
 CMapLoaderJson::MapObjectLoader::MapObjectLoader(CMapLoaderJson * _owner, JsonMap::value_type & json):

+ 5 - 3
lib/mapping/MapReaderH3M.cpp

@@ -410,9 +410,11 @@ bool MapReaderH3M::readBool()
 int8_t MapReaderH3M::readInt8Checked(int8_t lowerLimit, int8_t upperLimit)
 {
 	int8_t result = readInt8();
-	assert(result >= lowerLimit);
-	assert(result <= upperLimit);
-	return std::clamp(result, lowerLimit, upperLimit);
+	int8_t resultClamped = std::clamp(result, lowerLimit, upperLimit);
+	if (result != resultClamped)
+		logGlobal->warn("Map contains out of range value %d! Expected %d-%d", static_cast<int>(result), static_cast<int>(lowerLimit), static_cast<int>(upperLimit));
+
+	return resultClamped;
 }
 
 uint8_t MapReaderH3M::readUInt8()