aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2014-02-08 21:57:28 +0100
committerjackpoz <giacomopoz@gmail.com>2014-02-08 21:59:35 +0100
commitdbed818f6fe435a02d10f110e2c0883a53330230 (patch)
tree58852a7eac3a7befba9f1bf51bace9b159acabe9
parentaaa4b3a1240b7b25a4050a7c6d3dc5184f3e581d (diff)
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)
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp12
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h1
2 files changed, 13 insertions, 0 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index bd51fe0a85b..49beb0ae86f 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -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())
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 2e1068d1bff..861da6d86d2 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -222,6 +222,7 @@ class SmartScript
SmartAIEventList mEvents;
SmartAIEventList mInstallEvents;
SmartAIEventList mTimedActionList;
+ bool isProcessingTimedActionList;
Creature* me;
uint64 meOrigGUID;
GameObject* go;