1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-29 21:56:54 +02:00

Fix memory corruption during loading artifacts from mods

This commit is contained in:
Vadim Markovtsev 2016-10-22 10:00:55 +02:00
parent feaccead36
commit baa7a84db3
8 changed files with 37 additions and 28 deletions

@ -439,13 +439,13 @@ void CArtHandler::loadGrowingArt(CGrowingArtifact * art, const JsonNode & node)
{ {
for (auto b : node["growing"]["bonusesPerLevel"].Vector()) for (auto b : node["growing"]["bonusesPerLevel"].Vector())
{ {
auto bonus = JsonUtils::parseBonus (b["bonus"]); art->bonusesPerLevel.push_back(std::pair <ui16, Bonus>(b["level"].Float(), Bonus()));
art->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *bonus)); JsonUtils::parseBonus(b["bonus"], &art->bonusesPerLevel.back().second);
} }
for (auto b : node["growing"]["thresholdBonuses"].Vector()) for (auto b : node["growing"]["thresholdBonuses"].Vector())
{ {
auto bonus = JsonUtils::parseBonus (b["bonus"]); art->thresholdBonuses.push_back(std::pair <ui16, Bonus>(b["level"].Float(), Bonus()));
art->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *bonus)); JsonUtils::parseBonus(b["bonus"], &art->thresholdBonuses.back().second);
} }
} }

@ -98,7 +98,7 @@ public:
std::vector <std::pair <ui16, Bonus> > bonusesPerLevel; //bonus given each n levels std::vector <std::pair <ui16, Bonus> > bonusesPerLevel; //bonus given each n levels
std::vector <std::pair <ui16, Bonus> > thresholdBonuses; //after certain level they will be added once std::vector <std::pair <ui16, Bonus> > thresholdBonuses; //after certain level they will be added once
void levelUpArtifact (CArtifactInstance * art) override; void levelUpArtifact(CArtifactInstance * art) override;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {

@ -54,8 +54,10 @@ void CIdentifierStorage::checkIdentifier(std::string & ID)
} }
} }
CIdentifierStorage::ObjectCallback::ObjectCallback(std::string localScope, std::string remoteScope, std::string type, CIdentifierStorage::ObjectCallback::ObjectCallback(
std::string name, const std::function<void(si32)> & callback, bool optional): std::string localScope, std::string remoteScope, std::string type,
std::string name, const std::function<void(si32)> & callback,
bool optional):
localScope(localScope), localScope(localScope),
remoteScope(remoteScope), remoteScope(remoteScope),
type(type), type(type),

@ -41,7 +41,10 @@ class CIdentifierStorage
std::function<void(si32)> callback; std::function<void(si32)> callback;
bool optional; bool optional;
ObjectCallback(std::string localScope, std::string remoteScope, std::string type, std::string name, const std::function<void(si32)> & callback, bool optional); ObjectCallback(std::string localScope, std::string remoteScope,
std::string type, std::string name,
const std::function<void(si32)> & callback,
bool optional);
}; };
struct ObjectData // entry created on ID registration struct ObjectData // entry created on ID registration

@ -1110,10 +1110,6 @@ Bonus::Bonus()
sid = 0; sid = 0;
} }
Bonus::~Bonus()
{
}
std::shared_ptr<Bonus> Bonus::addPropagator(TPropagatorPtr Propagator) std::shared_ptr<Bonus> Bonus::addPropagator(TPropagatorPtr Propagator)
{ {
propagator = Propagator; propagator = Propagator;

@ -313,7 +313,6 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1); Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1);
Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype=-1, ValueType ValType = ADDITIVE_VALUE); Bonus(ui16 Dur, BonusType Type, BonusSource Src, si32 Val, ui32 ID, si32 Subtype=-1, ValueType ValType = ADDITIVE_VALUE);
Bonus(); Bonus();
~Bonus();
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {

@ -378,7 +378,7 @@ const T & parseByMap(const std::map<std::string, T> & map, const JsonNode * val,
return defaultValue; return defaultValue;
} }
void JsonUtils::resolveIdentifier (si32 &var, const JsonNode &node, std::string name) void JsonUtils::resolveIdentifier(si32 &var, const JsonNode &node, std::string name)
{ {
const JsonNode &value = node[name]; const JsonNode &value = node[name];
if (!value.isNull()) if (!value.isNull())
@ -400,7 +400,7 @@ void JsonUtils::resolveIdentifier (si32 &var, const JsonNode &node, std::string
} }
} }
void JsonUtils::resolveIdentifier (const JsonNode &node, si32 &var) void JsonUtils::resolveIdentifier(const JsonNode &node, si32 &var)
{ {
switch (node.getType()) switch (node.getType())
{ {
@ -408,7 +408,7 @@ void JsonUtils::resolveIdentifier (const JsonNode &node, si32 &var)
var = node.Float(); var = node.Float();
break; break;
case JsonNode::DATA_STRING: case JsonNode::DATA_STRING:
VLC->modh->identifiers.requestIdentifier (node, [&](si32 identifier) VLC->modh->identifiers.requestIdentifier(node, [&](si32 identifier)
{ {
var = identifier; var = identifier;
}); });
@ -420,8 +420,16 @@ void JsonUtils::resolveIdentifier (const JsonNode &node, si32 &var)
std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability) std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
{ {
auto b = std::make_shared<Bonus>(); auto b = std::make_shared<Bonus>();
if (!parseBonus(ability, b.get()))
{
return nullptr;
}
return b;
}
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
{
const JsonNode *value; const JsonNode *value;
std::string type = ability["type"].String(); std::string type = ability["type"].String();
@ -429,11 +437,11 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
if (it == bonusNameMap.end()) if (it == bonusNameMap.end())
{ {
logGlobal->errorStream() << "Error: invalid ability type " << type; logGlobal->errorStream() << "Error: invalid ability type " << type;
return b; return false;
} }
b->type = it->second; b->type = it->second;
resolveIdentifier (b->subtype, ability, "subtype"); resolveIdentifier(b->subtype, ability, "subtype");
b->val = ability["val"].Float(); b->val = ability["val"].Float();
@ -441,7 +449,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
if (!value->isNull()) if (!value->isNull())
b->valType = static_cast<Bonus::ValueType>(parseByMap(bonusValueMap, value, "value type ")); b->valType = static_cast<Bonus::ValueType>(parseByMap(bonusValueMap, value, "value type "));
resolveIdentifier (b->additionalInfo, ability, "addInfo"); resolveIdentifier(b->additionalInfo, ability, "addInfo");
b->turnsRemain = ability["turns"].Float(); b->turnsRemain = ability["turns"].Float();
@ -499,7 +507,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
const JsonVector vec = limiter["parameters"].Vector(); const JsonVector vec = limiter["parameters"].Vector();
VLC->modh->identifiers.requestIdentifier("creature", vec[0], [=](si32 creature) VLC->modh->identifiers.requestIdentifier("creature", vec[0], [=](si32 creature)
{ {
l2->setCreature (CreatureID(creature)); l2->setCreature(CreatureID(creature));
}); });
if (vec.size() > 1) if (vec.size() > 1)
{ {
@ -516,7 +524,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
const JsonVector vec = limiter["parameters"].Vector(); const JsonVector vec = limiter["parameters"].Vector();
std::string anotherBonusType = vec[0].String(); std::string anotherBonusType = vec[0].String();
auto it = bonusNameMap.find (anotherBonusType); auto it = bonusNameMap.find(anotherBonusType);
if (it == bonusNameMap.end()) if (it == bonusNameMap.end())
{ {
logGlobal->errorStream() << "Error: invalid ability type " << anotherBonusType; logGlobal->errorStream() << "Error: invalid ability type " << anotherBonusType;
@ -526,7 +534,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
if (vec.size() > 1 ) if (vec.size() > 1 )
{ {
resolveIdentifier (vec[1], l2->subtype); resolveIdentifier(vec[1], l2->subtype);
l2->isSubtypeRelevant = true; l2->isSubtypeRelevant = true;
} }
l = l2; l = l2;
@ -542,7 +550,7 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability)
if (!value->isNull()) if (!value->isNull())
b->propagator = parseByMap(bonusPropagatorMap, value, "propagator type "); b->propagator = parseByMap(bonusPropagatorMap, value, "propagator type ");
return b; return true;
} }
//returns first Key with value equal to given one //returns first Key with value equal to given one

@ -130,11 +130,12 @@ namespace JsonUtils
DLL_LINKAGE void parseTypedBonusShort(const JsonVector &source, std::shared_ptr<Bonus> dest); DLL_LINKAGE void parseTypedBonusShort(const JsonVector &source, std::shared_ptr<Bonus> dest);
/// ///
DLL_LINKAGE std::shared_ptr<Bonus> parseBonus (const JsonVector &ability_vec); DLL_LINKAGE std::shared_ptr<Bonus> parseBonus(const JsonVector &ability_vec);
DLL_LINKAGE std::shared_ptr<Bonus> parseBonus (const JsonNode &bonus); DLL_LINKAGE std::shared_ptr<Bonus> parseBonus(const JsonNode &ability);
DLL_LINKAGE bool parseBonus(const JsonNode &ability, Bonus *placement);
DLL_LINKAGE void unparseBonus (JsonNode &node, const std::shared_ptr<Bonus>& bonus); DLL_LINKAGE void unparseBonus (JsonNode &node, const std::shared_ptr<Bonus>& bonus);
DLL_LINKAGE void resolveIdentifier (si32 &var, const JsonNode &node, std::string name); DLL_LINKAGE void resolveIdentifier(si32 &var, const JsonNode &node, std::string name);
DLL_LINKAGE void resolveIdentifier (const JsonNode &node, si32 &var); DLL_LINKAGE void resolveIdentifier(const JsonNode &node, si32 &var);
/** /**
* @brief recursively merges source into dest, replacing identical fields * @brief recursively merges source into dest, replacing identical fields