mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-04 13:42:55 +01:00
protect objects against invalid allocation ids
This commit is contained in:
@@ -66,6 +66,7 @@ static uint32 AllocateImageList(uint32 count)
|
||||
static void FreeImageList(uint32 baseImageId, uint32 count)
|
||||
{
|
||||
Guard::Assert(_initialised);
|
||||
Guard::Assert(baseImageId >= BASE_IMAGE_ID);
|
||||
|
||||
// TODO validate that this was an allocated list
|
||||
_freeLists.push_back({ baseImageId, count });
|
||||
@@ -95,6 +96,9 @@ extern "C"
|
||||
|
||||
void gfx_object_free_images(uint32 baseImageId, uint32 count)
|
||||
{
|
||||
FreeImageList(baseImageId, count);
|
||||
if (baseImageId != 0)
|
||||
{
|
||||
FreeImageList(baseImageId, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,11 +355,14 @@ rct_string_id language_allocate_object_string(const utf8 * target)
|
||||
|
||||
void language_free_object_string(rct_string_id stringId)
|
||||
{
|
||||
if (_languageCurrent != nullptr)
|
||||
if (stringId != 0)
|
||||
{
|
||||
_languageCurrent->SetString(stringId, nullptr);
|
||||
if (_languageCurrent != nullptr)
|
||||
{
|
||||
_languageCurrent->SetString(stringId, nullptr);
|
||||
}
|
||||
_availableObjectStringIds.push(stringId);
|
||||
}
|
||||
_availableObjectStringIds.push(stringId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,9 +31,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void BannerObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.banner.scrolling_mode = stream->ReadValue<uint8>();
|
||||
_legacyType.banner.flags = stream->ReadValue<uint8>();
|
||||
_legacyType.banner.price = stream->ReadValue<uint8>();
|
||||
@@ -72,6 +70,9 @@ void BannerObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void BannerObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
class BannerObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_entry _legacyType;
|
||||
rct_object_entry _sceneryTabEntry;
|
||||
rct_scenery_entry _legacyType = { 0 };
|
||||
rct_object_entry _sceneryTabEntry = { 0 };
|
||||
|
||||
public:
|
||||
explicit BannerObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -30,8 +30,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void EntranceObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.string_idx = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image_id = stream->ReadValue<uint32>();
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.scrolling_mode = stream->ReadValue<uint8>();
|
||||
_legacyType.text_height = stream->ReadValue<uint8>();
|
||||
|
||||
@@ -49,6 +48,9 @@ void EntranceObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.string_idx);
|
||||
gfx_object_free_images(_legacyType.image_id, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.string_idx = 0;
|
||||
_legacyType.image_id = 0;
|
||||
}
|
||||
|
||||
void EntranceObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C"
|
||||
class EntranceObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_entrance_type _legacyType;
|
||||
rct_entrance_type _legacyType = { 0 };
|
||||
|
||||
public:
|
||||
explicit EntranceObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -30,8 +30,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void FootpathItemObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.path_bit.flags = stream->ReadValue<uint16>();
|
||||
_legacyType.path_bit.draw_type = stream->ReadValue<uint8>();
|
||||
_legacyType.path_bit.tool_id = stream->ReadValue<uint8>();
|
||||
@@ -71,6 +70,9 @@ void FootpathItemObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void FootpathItemObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
class FootpathItemObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_entry _legacyType;
|
||||
rct_object_entry _sceneryTabEntry;
|
||||
rct_scenery_entry _legacyType = { 0 };
|
||||
rct_object_entry _sceneryTabEntry = { 0 };
|
||||
|
||||
public:
|
||||
explicit FootpathItemObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -31,9 +31,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void FootpathObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.string_idx = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
_legacyType.bridge_image = stream->ReadValue<uint32>();
|
||||
stream->Seek(10, STREAM_SEEK_CURRENT);
|
||||
_legacyType.var_0A = stream->ReadValue<uint8>();
|
||||
_legacyType.flags = stream->ReadValue<uint8>();
|
||||
_legacyType.scrolling_mode = stream->ReadValue<uint8>();
|
||||
@@ -60,6 +58,9 @@ void FootpathObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.string_idx);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.string_idx = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void FootpathObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C"
|
||||
class FootpathObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_footpath_entry _legacyType;
|
||||
rct_footpath_entry _legacyType = { 0 };
|
||||
|
||||
public:
|
||||
explicit FootpathObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -37,9 +37,7 @@ LargeSceneryObject::~LargeSceneryObject()
|
||||
|
||||
void LargeSceneryObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.large_scenery.tool_id = stream->ReadValue<uint8>();
|
||||
_legacyType.large_scenery.flags = stream->ReadValue<uint8>();
|
||||
_legacyType.large_scenery.price = stream->ReadValue<sint16>();
|
||||
@@ -115,6 +113,9 @@ void LargeSceneryObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void LargeSceneryObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
class LargeSceneryObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_entry _legacyType;
|
||||
rct_object_entry _sceneryTabEntry;
|
||||
rct_scenery_entry _legacyType = { 0 };
|
||||
rct_object_entry _sceneryTabEntry = { 0 };
|
||||
rct_large_scenery_text * _3dFont = nullptr;
|
||||
rct_large_scenery_tile * _tiles = nullptr;
|
||||
|
||||
|
||||
@@ -645,6 +645,7 @@ extern "C"
|
||||
Object * object = _loadedObjects[i];
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->Unload();
|
||||
object->Load();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ RideObject::~RideObject()
|
||||
void RideObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
stream->Read(&_legacyType);
|
||||
_legacyType.name = 0;
|
||||
_legacyType.description = 0;
|
||||
_legacyType.images_offset = 0;
|
||||
|
||||
GetStringTable()->Read(context, stream, OBJ_STRING_ID_NAME);
|
||||
GetStringTable()->Read(context, stream, OBJ_STRING_ID_DESCRIPTION);
|
||||
@@ -311,6 +314,10 @@ void RideObject::Unload()
|
||||
language_free_object_string(_legacyType.name);
|
||||
language_free_object_string(_legacyType.description);
|
||||
gfx_object_free_images(_legacyType.images_offset, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.description = 0;
|
||||
_legacyType.images_offset = 0;
|
||||
}
|
||||
|
||||
void RideObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C"
|
||||
class RideObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_ride_entry _legacyType;
|
||||
rct_ride_entry _legacyType = { 0 };
|
||||
vehicle_colour_preset_list _presetColours = { 0 };
|
||||
sint8 * _peepLoadingPositions[4] = { nullptr };
|
||||
|
||||
|
||||
@@ -37,8 +37,7 @@ SceneryGroupObject::~SceneryGroupObject()
|
||||
|
||||
void SceneryGroupObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
stream->Seek(0x80 * 2, STREAM_SEEK_CURRENT);
|
||||
_legacyType.entry_count = stream->ReadValue<uint8>();
|
||||
_legacyType.var_107 = stream->ReadValue<uint8>();
|
||||
@@ -84,6 +83,9 @@ void SceneryGroupObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void SceneryGroupObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -28,9 +28,9 @@ struct ObjectRepositoryItem;
|
||||
class SceneryGroupObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_set_entry _legacyType;
|
||||
uint32 _numItems;
|
||||
rct_object_entry * _items;
|
||||
rct_scenery_set_entry _legacyType = { 0 };
|
||||
uint32 _numItems = 0;
|
||||
rct_object_entry * _items = nullptr;
|
||||
|
||||
public:
|
||||
explicit SceneryGroupObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -37,9 +37,7 @@ SmallSceneryObject::~SmallSceneryObject()
|
||||
|
||||
void SmallSceneryObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.small_scenery.flags = stream->ReadValue<uint32>();
|
||||
_legacyType.small_scenery.height = stream->ReadValue<uint8>();
|
||||
_legacyType.small_scenery.tool_id = stream->ReadValue<uint8>();
|
||||
@@ -103,15 +101,13 @@ void SmallSceneryObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void SmallSceneryObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
{
|
||||
// rct_drawpixelinfo clipDPI;
|
||||
// if (!clip_drawpixelinfo(&clipDPI, dpi, x - 56, y - 56, 112, 112)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
uint32 flags = _legacyType.small_scenery.flags;
|
||||
uint32 imageId = _legacyType.image;
|
||||
if (flags & SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
class SmallSceneryObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_entry _legacyType;
|
||||
rct_object_entry _sceneryTabEntry;
|
||||
rct_scenery_entry _legacyType = { 0 };
|
||||
rct_object_entry _sceneryTabEntry = { 0 };
|
||||
uint8 * _var10data = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
@@ -31,9 +31,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void StexObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.scenario_name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.park_name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.details = stream->ReadValue<rct_string_id>();
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.var_06 = stream->ReadValue<uint8>();
|
||||
stream->Seek(1, STREAM_SEEK_CURRENT);
|
||||
|
||||
@@ -54,6 +52,10 @@ void StexObject::Unload()
|
||||
language_free_object_string(_legacyType.scenario_name);
|
||||
language_free_object_string(_legacyType.park_name);
|
||||
language_free_object_string(_legacyType.details);
|
||||
|
||||
_legacyType.scenario_name = 0;
|
||||
_legacyType.park_name = 0;
|
||||
_legacyType.details = 0;
|
||||
}
|
||||
|
||||
void StexObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C"
|
||||
class StexObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_stex_entry _legacyType;
|
||||
rct_stex_entry _legacyType = { 0 };
|
||||
|
||||
public:
|
||||
explicit StexObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -31,9 +31,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void WallObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image = stream->ReadValue<uint32>();
|
||||
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.wall.tool_id = stream->ReadValue<uint8>();
|
||||
_legacyType.wall.flags = stream->ReadValue<uint8>();
|
||||
_legacyType.wall.height = stream->ReadValue<uint8>();
|
||||
@@ -75,6 +73,9 @@ void WallObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.name);
|
||||
gfx_object_free_images(_legacyType.image, GetImageTable()->GetCount());
|
||||
|
||||
_legacyType.name = 0;
|
||||
_legacyType.image = 0;
|
||||
}
|
||||
|
||||
void WallObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,8 +26,8 @@ extern "C"
|
||||
class WallObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_scenery_entry _legacyType;
|
||||
rct_object_entry _sceneryTabEntry;
|
||||
rct_scenery_entry _legacyType = { 0 };
|
||||
rct_object_entry _sceneryTabEntry = { 0 };
|
||||
|
||||
public:
|
||||
explicit WallObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -30,8 +30,7 @@ enum OBJ_STRING_ID
|
||||
|
||||
void WaterObject::ReadLegacy(IReadObjectContext * context, IStream * stream)
|
||||
{
|
||||
_legacyType.string_idx = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.image_id = stream->ReadValue<uint32>();
|
||||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
_legacyType.var_06 = stream->ReadValue<uint32>();
|
||||
_legacyType.var_0A = stream->ReadValue<uint32>();
|
||||
_legacyType.var_0E = stream->ReadValue<uint16>();
|
||||
@@ -54,6 +53,8 @@ void WaterObject::Load()
|
||||
void WaterObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.string_idx);
|
||||
|
||||
_legacyType.string_idx = 0;
|
||||
}
|
||||
|
||||
void WaterObject::DrawPreview(rct_drawpixelinfo * dpi) const
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C"
|
||||
class WaterObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_water_type _legacyType;
|
||||
rct_water_type _legacyType = { 0 };
|
||||
|
||||
public:
|
||||
explicit WaterObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
@@ -507,7 +507,7 @@ extern "C"
|
||||
}
|
||||
delete s6exporter;
|
||||
|
||||
// reset_loaded_objects();
|
||||
reset_loaded_objects();
|
||||
gfx_invalidate_screen();
|
||||
|
||||
if (result && !(flags & S6_SAVE_FLAG_AUTOMATIC))
|
||||
|
||||
Reference in New Issue
Block a user