diff options
| author | jackpoz <giacomopoz@gmail.com> | 2014-01-12 20:23:13 +0100 | 
|---|---|---|
| committer | jackpoz <giacomopoz@gmail.com> | 2014-01-12 20:23:13 +0100 | 
| commit | b8625f41bd6131e7fb3ff126780da18d5d2959fd (patch) | |
| tree | a873f70261a5abd618fd17519bccee890b0e7ec6 /src | |
| parent | de1d75af7085509084857586d0d03cfe51c5c0de (diff) | |
Core/SAI: Fix crash in SmartScript
Fix crash in SmartScript storing WorldObject* instead of guid as targets in SmartScript::mTargetStorage , used by SMART_TARGET_STORED target type , SMART_ESCORT_TARGETS and other escort related code.
Fixes #11228 , #10157 .
Valgrind log:
 Invalid read of size 4
  at : Object::GetTypeId() const (Object.h:140)
  by : SmartScript::IsPlayer(WorldObject*) (SmartScript.h:73)
  by : SmartScript::ProcessAction(SmartScriptHolder&, Unit*, unsigned int, unsigned int, bool, SpellInfo const*, GameObject*) (SmartScript.cpp:330)
  by : SmartScript::ProcessEvent(SmartScriptHolder&, Unit*, unsigned int, unsigned int, bool, SpellInfo const*, GameObject*) (SmartScript.cpp:2662)
  by : SmartScript::ProcessAction(SmartScriptHolder&, Unit*, unsigned int, unsigned int, bool, SpellInfo const*, GameObject*) (SmartScript.cpp:2226)
  by : SmartScript::ProcessTimedAction(SmartScriptHolder&, unsigned int const&, unsigned int const&, Unit*, unsigned int, unsigned int, bool, SpellInfo const*, GameObject*) (SmartScript.cpp:2238)
  by : SmartScript::ProcessEvent(SmartScriptHolder&, Unit*, unsigned int, unsigned int, bool, SpellInfo const*, GameObject*) (SmartScript.cpp:2685)
  by : SmartScript::UpdateTimer(SmartScriptHolder&, unsigned int) (SmartScript.cpp:3198)
  by : SmartScript::OnUpdate(unsigned int) (SmartScript.cpp:3244)
  by : SmartAI::UpdateAI(unsigned int) (SmartAI.cpp:331)
  by : Creature::Update(unsigned int) (Creature.cpp:544)
  by : void Trinity::ObjectUpdater::Visit<Creature>(GridRefManager<Creature>&) (GridNotifiers.cpp:340)
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 5 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 6 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 51 | 
3 files changed, 57 insertions, 5 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 5efab2214b6..bd51fe0a85b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2551,7 +2551,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*          {              ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id);              if (itr != mTargetStorage->end()) -                l->assign(itr->second->begin(), itr->second->end()); +            { +                ObjectList* objectList = itr->second->GetObjectList(); +                l->assign(objectList->begin(), objectList->end()); +            }              return l;          } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 56b3674bd73..2e1068d1bff 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -99,13 +99,13 @@ class SmartScript              if (mTargetStorage->find(id) != mTargetStorage->end())              {                  // check if already stored -                if ((*mTargetStorage)[id] == targets) +                if ((*mTargetStorage)[id]->Equals(targets))                      return;                  delete (*mTargetStorage)[id];              } -            (*mTargetStorage)[id] = targets; +            (*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject());          }          bool IsSmart(Creature* c = NULL) @@ -141,7 +141,7 @@ class SmartScript          {              ObjectListMap::iterator itr = mTargetStorage->find(id);              if (itr != mTargetStorage->end()) -                return (*itr).second; +                return (*itr).second->GetObjectList();              return NULL;          } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index be074c2939f..08ef71771e5 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1321,7 +1321,56 @@ struct SmartScriptHolder  typedef UNORDERED_MAP<uint32, WayPoint*> WPPath;  typedef std::list<WorldObject*> ObjectList; -typedef UNORDERED_MAP<uint32, ObjectList*> ObjectListMap; +typedef std::list<uint64> GuidList; +class ObjectGuidList +{ +    ObjectList* m_objectList; +    GuidList* m_guidList; +    WorldObject* m_baseObject; + +public: +    ObjectGuidList(ObjectList* objectList, WorldObject* baseObject) +    { +        ASSERT(objectList != NULL); +        ASSERT(baseObject != NULL); +        m_objectList = objectList; +        m_baseObject = baseObject; +        m_guidList = new GuidList(); + +        for (ObjectList::iterator itr = objectList->begin(); itr != objectList->end(); ++itr) +        { +            m_guidList->push_back((*itr)->GetGUID()); +        } +    } + +    ObjectList* GetObjectList() +    { +        //sanitize list using m_guidList +        m_objectList->clear(); + +        for (GuidList::iterator itr = m_guidList->begin(); itr != m_guidList->end(); ++itr) +        { +            if (WorldObject* obj = ObjectAccessor::GetWorldObject(*m_baseObject, *itr)) +                m_objectList->push_back(obj); +            else +                TC_LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: " UI64FMTD, *itr); +        } + +        return m_objectList; +    } + +    bool Equals(ObjectList* objectList) +    { +        return m_objectList == objectList; +    } + +    ~ObjectGuidList() +    { +        delete m_objectList; +        delete m_guidList; +    } +}; +typedef UNORDERED_MAP<uint32, ObjectGuidList*> ObjectListMap;  class SmartWaypointMgr  {  | 
