From 001fdc3682bd514b31f7c3a0a916720af056b00b Mon Sep 17 00:00:00 2001 From: rubidium Date: Sun, 12 May 2013 13:12:55 +0000 Subject: (svn r25236) -Fix [FS#5547]: crash when AI is executing a command as it is bankrupted (removed from the game) The command is placed in a queue for processing before it is bankrupted, after that the command is executed. This command yields a failure because the company does not exist, but then it still needs to call the callback. This callback tries to access the AI's virtual machine without any checks, so it starts to read a just freed pointer and segfaults. --- src/ai/ai_instance.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 4d808e055..f109a0926 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -238,8 +238,17 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) */ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { - Company::Get(_current_company)->ai_instance->DoCommandCallback(result, tile, p1, p2); - Company::Get(_current_company)->ai_instance->Continue(); + /* + * The company might not exist anymore. Check for this. + * The command checks are not useful since this callback + * is also called when the command fails, which is does + * when the company does not exist anymore. + */ + const Company *c = Company::GetIfValid(_current_company); + if (c == NULL || c->ai_instance == NULL) return; + + c->ai_instance->DoCommandCallback(result, tile, p1, p2); + c->ai_instance->Continue(); } CommandCallback *AIInstance::GetDoCommandCallback() -- cgit v1.2.3-70-g09d2