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.
pull/495/head
Rubidium 1 year ago committed by rubidium42
parent 717f79ff22
commit 1e4a89177e

@ -29,7 +29,7 @@ ScriptCompanyMode::~ScriptCompanyMode()
/* static */ bool ScriptCompanyMode::IsValid()
{
return ScriptObject::GetCompany() != OWNER_DEITY;
return ::Company::IsValidID(ScriptObject::GetCompany());
}
/* static */ bool ScriptCompanyMode::IsDeity()

@ -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().
*/

@ -253,7 +253,7 @@ std::tuple<bool, bool, bool> 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 };
}

Loading…
Cancel
Save