1
0
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:
Ted John
2016-07-03 18:02:18 +01:00
parent 80381cfaa0
commit 52928e1e08
26 changed files with 78 additions and 54 deletions

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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;

View File

@@ -645,6 +645,7 @@ extern "C"
Object * object = _loadedObjects[i];
if (object != nullptr)
{
object->Unload();
object->Load();
}
}

View File

@@ -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

View File

@@ -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 };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -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

View File

@@ -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) { };

View File

@@ -507,7 +507,7 @@ extern "C"
}
delete s6exporter;
// reset_loaded_objects();
reset_loaded_objects();
gfx_invalidate_screen();
if (result && !(flags & S6_SAVE_FLAG_AUTOMATIC))