Core/SAI: Fix crash

Disable script type SMART_SCRIPT_TYPE_TIMED_ACTIONLIST actions if they are trying to overwrite the timed action list while iterating it.
This was invalidating the iterator and deleting any smart action stored in it, including the current executed one.

Valgrind log:
 Invalid read of size 1
  at SmartScript::OnUpdate(unsigned int) (SmartScript.cpp:3258)
  by SmartAI::UpdateAI(unsigned int) (SmartAI.cpp:331)
  by Creature::Update(unsigned int) (Creature.cpp:544)
 Address 0x1807d9b2 is 10 bytes after a block of size 40 alloc'd
  at operator new(unsigned long) (vg_replace_malloc.c:319)
  ...
  by SmartAIMgr::LoadSmartAIFromDB() (SmartScriptMgr.cpp:231)
  by World::SetInitialWorldSettings() (World.cpp:1724)
  by Master::Run() (Master.cpp:169)
  by main (Main.cpp:142)
This commit is contained in:
jackpoz
2014-02-08 21:57:28 +01:00
parent aaa4b3a124
commit dbed818f6f
2 changed files with 13 additions and 0 deletions

View File

@@ -76,6 +76,7 @@ SmartScript::SmartScript()
goOrigGUID = 0;
mLastInvoker = 0;
mScriptType = SMART_SCRIPT_TYPE_CREATURE;
isProcessingTimedActionList = false;
}
SmartScript::~SmartScript()
@@ -3253,6 +3254,7 @@ void SmartScript::OnUpdate(uint32 const diff)
bool needCleanup = true;
if (!mTimedActionList.empty())
{
isProcessingTimedActionList = true;
for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
{
if ((*i).enableTimed)
@@ -3261,6 +3263,8 @@ void SmartScript::OnUpdate(uint32 const diff)
needCleanup = false;
}
}
isProcessingTimedActionList = false;
}
if (needCleanup)
mTimedActionList.clear();
@@ -3502,6 +3506,14 @@ Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly)
void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
{
//do NOT clear mTimedActionList if it's being iterated because it will invalidate the iterator and delete
// any SmartScriptHolder contained like the "e" parameter passed to this function
if (isProcessingTimedActionList)
{
TC_LOG_ERROR("scripts.ai", "Entry %d SourceType %u Event %u Action %u is trying to overwrite timed action list from a timed action, this is not allowed!.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
return;
}
mTimedActionList.clear();
mTimedActionList = sSmartScriptMgr->GetScript(entry, SMART_SCRIPT_TYPE_TIMED_ACTIONLIST);
if (mTimedActionList.empty())