Changeset - r27008:1819ba4d5c84
[Not reviewed]
master
0 3 0
Rubidium - 15 months ago 2023-03-02 20:27:30
rubidium@openttd.org
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.
3 files changed with 3 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/script/api/script_companymode.cpp
Show inline comments
 
@@ -29,7 +29,7 @@ ScriptCompanyMode::~ScriptCompanyMode()
 

	
 
/* static */ bool ScriptCompanyMode::IsValid()
 
{
 
	return ScriptObject::GetCompany() != OWNER_DEITY;
 
	return ::Company::IsValidID(ScriptObject::GetCompany());
 
}
 

	
 
/* static */ bool ScriptCompanyMode::IsDeity()
src/script/api/script_companymode.hpp
Show inline comments
 
@@ -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().
 
	 */
src/script/api/script_object.cpp
Show inline comments
 
@@ -253,7 +253,7 @@ std::tuple<bool, bool, bool> ScriptObjec
 

	
 
	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 };
 
	}
0 comments (0 inline, 0 general)