mirror of https://github.com/OpenTTD/OpenTTD
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/10559/head
parent
717f79ff22
commit
1e4a89177e
|
@ -29,7 +29,7 @@ ScriptCompanyMode::~ScriptCompanyMode()
|
||||||
|
|
||||||
/* static */ bool ScriptCompanyMode::IsValid()
|
/* static */ bool ScriptCompanyMode::IsValid()
|
||||||
{
|
{
|
||||||
return ScriptObject::GetCompany() != OWNER_DEITY;
|
return ::Company::IsValidID(ScriptObject::GetCompany());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptCompanyMode::IsDeity()
|
/* static */ bool ScriptCompanyMode::IsDeity()
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether a company mode is valid. In other words, are commands
|
* 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.
|
* @return true When a company mode is valid.
|
||||||
* @post !ScriptCompanyMode::IsDeity().
|
* @post !ScriptCompanyMode::IsDeity().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -253,7 +253,7 @@ std::tuple<bool, bool, bool> ScriptObject::DoCommandPrep()
|
||||||
|
|
||||||
bool networking = _networking && !_generating_world;
|
bool networking = _networking && !_generating_world;
|
||||||
|
|
||||||
if (ScriptCompanyMode::IsValid() && !::Company::IsValidID(ScriptObject::GetCompany())) {
|
if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) {
|
||||||
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
|
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
|
||||||
return { true, estimate_only, networking };
|
return { true, estimate_only, networking };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue