From 0aade935aa213a6d9d95253e55dbedea3682c599 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 6 Mar 2019 19:11:21 +0000 Subject: [PATCH] Fix #8824: invalid read in footpath_chain_ride_queue (#8831) --- distribution/changelog.txt | 1 + src/openrct2/ride/Ride.cpp | 19 +++++---- src/openrct2/world/Footpath.cpp | 68 ++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index ed85c9d366..ece7e42a48 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -78,6 +78,7 @@ - Fix: [#8742] Access violation in vehicle_update_sound_params. - Fix: [#8804] Raising water shows money effect at the bottom rather than new height. - Fix: [#8811] Some fields in the sv6 save file not being copied correctly. +- Fix: [#8824] Invalid read in footpath_chain_ride_queue. - Improved: [#2940] Allow mouse-dragging to set patrol area (Singleplayer only). - Improved: [#7730] Draw extreme vertical and lateral Gs red in the ride window's graph tab. - Improved: [#7930] Automatically create folders for custom content. diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 708d7f64ae..cadff985bd 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4173,16 +4173,19 @@ static void sub_6B5952(Ride* ride) // This will fire for every entrance on this x, y and z, regardless whether that actually belongs to // the ride or not. TileElement* tileElement = map_get_first_element_at(location.x, location.y); - do + if (tileElement != nullptr) { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) - continue; - if (tileElement->base_height != z) - continue; + do + { + if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) + continue; + if (tileElement->base_height != z) + continue; - int32_t direction = tileElement->GetDirection(); - footpath_chain_ride_queue(ride->id, i, x, y, tileElement, direction_reverse(direction)); - } while (!(tileElement++)->IsLastForTile()); + int32_t direction = tileElement->GetDirection(); + footpath_chain_ride_queue(ride->id, i, x, y, tileElement, direction_reverse(direction)); + } while (!(tileElement++)->IsLastForTile()); + } } } diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 7222e6bf9e..3795e43c5a 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1247,33 +1247,36 @@ void footpath_chain_ride_queue( x += CoordsDirectionDelta[direction].x; y += CoordsDirectionDelta[direction].y; tileElement = map_get_first_element_at(x >> 5, y >> 5); - do + if (tileElement != nullptr) { - if (lastQueuePathElement == tileElement) - continue; - if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - if (tileElement->base_height == z) + do { - if (tileElement->AsPath()->IsSloped()) + if (lastQueuePathElement == tileElement) + continue; + if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + if (tileElement->base_height == z) { - if (tileElement->AsPath()->GetSlopeDirection() != direction) - break; + if (tileElement->AsPath()->IsSloped()) + { + if (tileElement->AsPath()->GetSlopeDirection() != direction) + break; + } + goto foundNextPath; } - goto foundNextPath; - } - if (tileElement->base_height == z - 2) - { - if (!tileElement->AsPath()->IsSloped()) - break; + if (tileElement->base_height == z - 2) + { + if (!tileElement->AsPath()->IsSloped()) + break; - if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != direction) - break; + if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != direction) + break; - z -= 2; - goto foundNextPath; - } - } while (!(tileElement++)->IsLastForTile()); + z -= 2; + goto foundNextPath; + } + } while (!(tileElement++)->IsLastForTile()); + } break; foundNextPath: @@ -1371,18 +1374,21 @@ void footpath_update_queue_chains() continue; TileElement* tileElement = map_get_first_element_at(location.x, location.y); - do + if (tileElement != nullptr) { - if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) - continue; - if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_RIDE_ENTRANCE) - continue; - if (tileElement->AsEntrance()->GetRideIndex() != rideIndex) - continue; + do + { + if (tileElement->GetType() != TILE_ELEMENT_TYPE_ENTRANCE) + continue; + if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_RIDE_ENTRANCE) + continue; + if (tileElement->AsEntrance()->GetRideIndex() != rideIndex) + continue; - uint8_t direction = tileElement->GetDirectionWithOffset(2); - footpath_chain_ride_queue(rideIndex, i, location.x << 5, location.y << 5, tileElement, direction); - } while (!(tileElement++)->IsLastForTile()); + uint8_t direction = tileElement->GetDirectionWithOffset(2); + footpath_chain_ride_queue(rideIndex, i, location.x << 5, location.y << 5, tileElement, direction); + } while (!(tileElement++)->IsLastForTile()); + } } } }