From 1e4a89177e88d44a4ac82acd7197a6ee79d46e66 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 2 Mar 2023 21:27:30 +0100 Subject: [PATCH] Fix: crashes to desktop from game scripts when companies disappear When a game script is in company mode, it pretends to be another company. When that company disappear (bankruptcy/merger), the game script still uses that company and it keeps calling functions as if it is that company. For example, ScriptEngine::IsBuildable internally dereferences Company without checks, causing a null dereference for any ScriptEngine function when called from a company scope of a company that has disappeared. Guard against this by extending the ScriptCompanyScope::IsValid check to also check for the company still being active. --- src/script/api/script_companymode.cpp | 2 +- src/script/api/script_companymode.hpp | 2 +- src/script/api/script_object.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/script/api/script_companymode.cpp b/src/script/api/script_companymode.cpp index ef738dc4ad..3a5c5f48f7 100644 --- a/src/script/api/script_companymode.cpp +++ b/src/script/api/script_companymode.cpp @@ -29,7 +29,7 @@ ScriptCompanyMode::~ScriptCompanyMode() /* static */ bool ScriptCompanyMode::IsValid() { - return ScriptObject::GetCompany() != OWNER_DEITY; + return ::Company::IsValidID(ScriptObject::GetCompany()); } /* static */ bool ScriptCompanyMode::IsDeity() diff --git a/src/script/api/script_companymode.hpp b/src/script/api/script_companymode.hpp index 6c2e13530f..8378e11c4c 100644 --- a/src/script/api/script_companymode.hpp +++ b/src/script/api/script_companymode.hpp @@ -50,7 +50,7 @@ public: /** * Check whether a company mode is valid. In other words, are commands - * being executed under some company. + * being executed under some company and does the company still exist? * @return true When a company mode is valid. * @post !ScriptCompanyMode::IsDeity(). */ diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 2c5156f0a6..f15b9d56ec 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -253,7 +253,7 @@ std::tuple ScriptObject::DoCommandPrep() bool networking = _networking && !_generating_world; - if (ScriptCompanyMode::IsValid() && !::Company::IsValidID(ScriptObject::GetCompany())) { + if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); return { true, estimate_only, networking }; }