Răsfoiți Sursa

Fix possible crashes on attempt to parse bonus

Ivan Savenko 4 luni în urmă
părinte
comite
464865f20d
2 a modificat fișierele cu 14 adăugiri și 12 ștergeri
  1. 7 11
      lib/CCreatureHandler.cpp
  2. 7 1
      lib/json/JsonBonus.cpp

+ 7 - 11
lib/CCreatureHandler.cpp

@@ -903,19 +903,15 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
 {
 {
 	creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]);
 	creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]);
 
 
-	//FIXME: MOD COMPATIBILITY
-	if (config["abilities"].getType() == JsonNode::JsonType::DATA_STRUCT)
+	for(const auto & ability : config["abilities"].Struct())
 	{
 	{
-		for(const auto & ability : config["abilities"].Struct())
+		if (!ability.second.isNull())
 		{
 		{
-			if (!ability.second.isNull())
-			{
-				auto b = JsonUtils::parseBonus(ability.second, creature->getBonusTextID(ability.first));
-				b->source = BonusSource::CREATURE_ABILITY;
-				b->sid = BonusSourceID(creature->getId());
-				b->duration = BonusDuration::PERMANENT;
-				creature->addNewBonus(b);
-			}
+			auto b = JsonUtils::parseBonus(ability.second, creature->getBonusTextID(ability.first));
+			b->source = BonusSource::CREATURE_ABILITY;
+			b->sid = BonusSourceID(creature->getId());
+			b->duration = BonusDuration::PERMANENT;
+			creature->addNewBonus(b);
 		}
 		}
 	}
 	}
 
 

+ 7 - 1
lib/json/JsonBonus.cpp

@@ -404,7 +404,7 @@ static TUpdaterPtr parseUpdater(const JsonNode & updaterJson)
 		if(updaterJson["type"].String() == "GROWS_WITH_LEVEL")
 		if(updaterJson["type"].String() == "GROWS_WITH_LEVEL")
 		{
 		{
 			// MOD COMPATIBILITY - parameters is deprecated in 1.7
 			// MOD COMPATIBILITY - parameters is deprecated in 1.7
-			const JsonVector param = updaterJson["parameters"].Vector();
+			const JsonNode & param = updaterJson["parameters"];
 			int valPer20 = updaterJson["valPer20"].isNull() ? param[0].Integer() : updaterJson["valPer20"].Integer();
 			int valPer20 = updaterJson["valPer20"].isNull() ? param[0].Integer() : updaterJson["valPer20"].Integer();
 			int stepSize = updaterJson["stepSize"].isNull() ? param[1].Integer() : updaterJson["stepSize"].Integer();
 			int stepSize = updaterJson["stepSize"].isNull() ? param[1].Integer() : updaterJson["stepSize"].Integer();
 
 
@@ -648,6 +648,12 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b, const TextIdentifi
 	const JsonNode & subtypeNode = ability["subtype"];
 	const JsonNode & subtypeNode = ability["subtype"];
 	const JsonNode & addinfoNode = ability["addInfo"];
 	const JsonNode & addinfoNode = ability["addInfo"];
 
 
+	if (ability["type"].isNull())
+	{
+		logMod->error("Failed to parse bonus. Description: '%s'. Config: '%s'", descriptionID.get(), ability.toCompactString());
+		return false;
+	}
+
 	LIBRARY->identifiers()->requestIdentifier("bonus", ability["type"], [b, subtypeNode, addinfoNode](si32 bonusID)
 	LIBRARY->identifiers()->requestIdentifier("bonus", ability["type"], [b, subtypeNode, addinfoNode](si32 bonusID)
 	{
 	{
 		b->type = static_cast<BonusType>(bonusID);
 		b->type = static_cast<BonusType>(bonusID);