From 6dc47a2de09272bac3c5b97668ccf2d9643b5649 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Thu, 8 Sep 2016 14:24:28 +0300 Subject: [PATCH] Fixed use-after-free crash with quests registration in RMG. * code taken from PR #200 --- lib/mapping/CMap.cpp | 39 +++++++++++++++++++++--------------- lib/mapping/CMap.h | 2 +- lib/mapping/MapFormatH3M.cpp | 4 ---- lib/rmg/CRmgTemplateZone.cpp | 7 ++----- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index ed2ae0b12..19f5b37ad 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -556,16 +556,9 @@ void CMap::eraseArtifactInstance(CArtifactInstance * art) artInstances[art->id.getNum()].dellNull(); } -void CMap::addQuest(CGObjectInstance * quest) -{ - auto q = dynamic_cast(quest); - q->quest->qid = quests.size(); - quests.push_back(q->quest); -} - void CMap::addNewObject(CGObjectInstance * obj) { - if(obj->id != ObjectInstanceID(objects.size())) + if(obj->id != ObjectInstanceID(objects.size())) throw std::runtime_error("Invalid object instance id"); if(obj->instanceName == "") @@ -573,19 +566,33 @@ void CMap::addNewObject(CGObjectInstance * obj) auto it = instanceNames.find(obj->instanceName); if(it != instanceNames.end()) - throw std::runtime_error("Object instance name duplicated:"+obj->instanceName); + throw std::runtime_error("Object instance name duplicated: "+obj->instanceName); - objects.push_back(obj); - instanceNames[obj->instanceName] = obj; - addBlockVisTiles(obj); + objects.push_back(obj); + instanceNames[obj->instanceName] = obj; + addBlockVisTiles(obj); - if(obj->ID == Obj::TOWN) + //todo: make this virtual method of CGObjectInstance + switch (obj->ID) { + case Obj::TOWN: towns.push_back(static_cast(obj)); - } - if(obj->ID == Obj::HERO) - { + break; + case Obj::HERO: heroesOnMap.push_back(static_cast(obj)); + break; + case Obj::SEER_HUT: + case Obj::QUEST_GUARD: + case Obj::BORDERGUARD: + case Obj::BORDER_GATE: + { + auto q = dynamic_cast(obj); + q->quest->qid = quests.size(); + quests.push_back(q->quest); + } + break; + default: + break; } } diff --git a/lib/mapping/CMap.h b/lib/mapping/CMap.h index 87ba1b994..5618ba4b4 100644 --- a/lib/mapping/CMap.h +++ b/lib/mapping/CMap.h @@ -313,7 +313,7 @@ public: void addNewArtifactInstance(CArtifactInstance * art); void eraseArtifactInstance(CArtifactInstance * art); - void addQuest(CGObjectInstance * quest); + void addNewObject(CGObjectInstance * obj); /// Gets object of specified type on requested position diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 8a49384d8..75614419b 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -1112,7 +1112,6 @@ void CMapLoaderH3M::readObjects() case Obj::SEER_HUT: { nobj = readSeerHut(); - map->addQuest(nobj); break; } case Obj::WITCH_HUT: @@ -1363,7 +1362,6 @@ void CMapLoaderH3M::readObjects() case Obj::QUEST_GUARD: { auto guard = new CGQuestGuard(); - map->addQuest(guard); readQuest(guard); nobj = guard; break; @@ -1400,13 +1398,11 @@ void CMapLoaderH3M::readObjects() case Obj::BORDERGUARD: { nobj = new CGBorderGuard(); - map->addQuest(nobj); break; } case Obj::BORDER_GATE: { nobj = new CGBorderGate(); - map->addQuest (nobj); break; } case Obj::PYRAMID: //Pyramid of WoG object diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 07969064a..673168877 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -451,7 +451,7 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen) if (gen->isPossible(nearbyPos)) gen->setOccupied(nearbyPos, ETileType::BLOCKED); }); - edge = true; + edge = true; } }); } @@ -2328,7 +2328,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject(CMapGenerator* gen, CTreasurePileIn continue; total += oi.probability; - + thresholds.push_back (std::make_pair (total, &oi)); } } @@ -2760,7 +2760,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen) obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false; gen->banQuestArt(artid); - gen->map->addQuest(obj); this->questArtZone->possibleObjects.push_back (generateArtInfo(artid)); @@ -2799,7 +2798,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen) obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false; gen->banQuestArt(artid); - gen->map->addQuest(obj); this->questArtZone->possibleObjects.push_back(generateArtInfo(artid)); @@ -2823,7 +2821,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen) obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false; gen->banQuestArt(artid); - gen->map->addQuest(obj); this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));