From 12067cb5587bc8d82a2e420ee214ab6f672dee4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 1 Aug 2017 07:24:31 +0200 Subject: [PATCH] Fix #4697: Ensure track designs are saved and read properly Previous code only set one byte as an end marker, but read and compared to 4 bytes, which could cause track design to become malformed. --- src/openrct2/object.h | 5 ++++- src/openrct2/ride/track_design.c | 8 ++++---- src/openrct2/ride/track_design_save.c | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/openrct2/object.h b/src/openrct2/object.h index 66cbf03af8..4435aaf83e 100644 --- a/src/openrct2/object.h +++ b/src/openrct2/object.h @@ -65,7 +65,10 @@ typedef enum * size: 0x10 */ typedef struct rct_object_entry { - uint32 flags; + union { + uint8 end_flag; // needed not to read past allocated buffer. + uint32 flags; + }; char name[8]; uint32 checksum; } rct_object_entry; diff --git a/src/openrct2/ride/track_design.c b/src/openrct2/ride/track_design.c index 17f01b672d..245a63bba6 100644 --- a/src/openrct2/ride/track_design.c +++ b/src/openrct2/ride/track_design.c @@ -365,7 +365,7 @@ static void track_design_load_scenery_objects(rct_track_td6 *td6) // Load scenery objects rct_td6_scenery_element *scenery = td6->scenery_elements; - for (; (scenery->scenery_object.flags & 0xFF) != 0xFF; scenery++) { + for (; (scenery->scenery_object.end_flag & 0xFF) != 0xFF; scenery++) { rct_object_entry * sceneryEntry = &scenery->scenery_object; object_manager_load_object(sceneryEntry); } @@ -378,7 +378,7 @@ static void track_design_load_scenery_objects(rct_track_td6 *td6) static void track_design_mirror_scenery(rct_track_td6 *td6) { rct_td6_scenery_element *scenery = td6->scenery_elements; - for (; (scenery->scenery_object.flags & 0xFF) != 0xFF; scenery++) { + for (; (scenery->scenery_object.end_flag & 0xFF) != 0xFF; scenery++) { uint8 entry_type, entry_index; if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index)) { entry_type = scenery->scenery_object.flags & 0xF; @@ -558,7 +558,7 @@ static void track_design_update_max_min_coordinates(sint16 x, sint16 y, sint16 z static sint32 track_design_place_scenery(rct_td6_scenery_element *scenery_start, uint8 rideIndex, sint32 originX, sint32 originY, sint32 originZ) { for (uint8 mode = 0; mode <= 1; mode++) { - if ((scenery_start->scenery_object.flags & 0xFF) != 0xFF) { + if ((scenery_start->scenery_object.end_flag & 0xFF) != 0xFF) { _trackDesignPlaceStateHasScenery = true; } @@ -566,7 +566,7 @@ static sint32 track_design_place_scenery(rct_td6_scenery_element *scenery_start, continue; } - for (rct_td6_scenery_element *scenery = scenery_start; (scenery->scenery_object.flags & 0xFF) != 0xFF; scenery++) { + for (rct_td6_scenery_element *scenery = scenery_start; (scenery->scenery_object.end_flag & 0xFF) != 0xFF; scenery++) { uint8 rotation = _currentTrackPieceDirection; rct_xy8 tile = { .x = originX / 32, .y = originY / 32 }; switch (rotation & 3){ diff --git a/src/openrct2/ride/track_design_save.c b/src/openrct2/ride/track_design_save.c index 5d8cbd20a0..c0f8b2511e 100644 --- a/src/openrct2/ride/track_design_save.c +++ b/src/openrct2/ride/track_design_save.c @@ -1159,7 +1159,7 @@ static size_t track_design_get_scenery_elements_count(rct_track_td6 *td6) size_t count = 0; rct_td6_scenery_element *sceneryElement = td6->scenery_elements; if (sceneryElement != NULL) { - while ((sceneryElement->scenery_object.flags & 0xFF) != 0xFF) { + while ((sceneryElement->scenery_object.end_flag & 0xFF) != 0xFF) { count++; sceneryElement++; }