1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-22 14:24:33 +01:00

Fix #7505: Crash when building path off map edge (#7587)

Validate map location before looping over the tile elements.
This commit is contained in:
Hielke Morsink
2018-06-01 11:30:41 +02:00
committed by Aaron van Geffen
parent b94f5ea9d8
commit 20fb4501d0
5 changed files with 31 additions and 21 deletions

View File

@@ -32,6 +32,7 @@
- Fix: [#7418] Staff walk off paths with a connection but no adjacent path.
- Fix: [#7436] Only the first 32 vehicles of a train can be painted.
- Fix: [#7480] Graphs skip values of 0.
- Fix: [#7505] Game crashes when trying to make path over map edge while having clearance checks disabled.
- Fix: [#7528] In park entrance pricing tab, switching tabs happens on mouse-down instead of mouse-up
- Fix: [#7544] Starting a headless server with no arguments causes the game to freeze.
- Fix: [#7571] Hovering a ride design over scenery or tracks will give tons of money.

View File

@@ -34,7 +34,7 @@
// This string specifies which version of network stream current build uses.
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "18"
#define NETWORK_STREAM_VERSION "19"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static rct_peep* _pickup_peep = nullptr;

View File

@@ -429,7 +429,7 @@ static money32 footpath_place_real(sint32 type, sint32 x, sint32 y, sint32 z, si
gFootpathPrice = 0;
gFootpathGroundFlags = 0;
if (x >= gMapSizeUnits || y >= gMapSizeUnits) {
if (map_is_edge(x, y)) {
gGameCommandErrorText = STR_OFF_EDGE_OF_MAP;
return MONEY32_UNDEFINED;
}
@@ -1057,18 +1057,13 @@ bool fence_in_the_way(sint32 x, sint32 y, sint32 z0, sint32 z1, sint32 direction
return false;
}
static bool map_is_edge(sint32 x, sint32 y)
{
return (
x < 32 ||
y < 32 ||
x >= gMapSizeUnits ||
y >= gMapSizeUnits
);
}
static rct_tile_element *footpath_connect_corners_get_neighbour(sint32 x, sint32 y, sint32 z, sint32 requireEdges)
{
if (!map_is_location_valid(x, y))
{
return nullptr;
}
rct_tile_element *tileElement = map_get_first_element_at(x >> 5, y >> 5);
do {
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
@@ -1082,6 +1077,7 @@ static rct_tile_element *footpath_connect_corners_get_neighbour(sint32 x, sint32
return tileElement;
} while (!(tileElement++)->IsLastForTile());
return nullptr;
}
@@ -2259,28 +2255,35 @@ static void footpath_remove_edges_towards_here(sint32 x, sint32 y, sint32 z, sin
*/
static void footpath_remove_edges_towards(sint32 x, sint32 y, sint32 z0, sint32 z1, sint32 direction, bool isQueue)
{
rct_tile_element *tileElement;
sint32 slope;
if (!map_is_location_valid(x, y))
{
return;
}
tileElement = map_get_first_element_at(x >> 5, y >> 5);
do {
rct_tile_element* tileElement = map_get_first_element_at(x >> 5, y >> 5);
do
{
if (tileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
continue;
if (z1 == tileElement->base_height) {
if (footpath_element_is_sloped(tileElement)) {
slope = footpath_element_get_slope_direction(tileElement);
if (z1 == tileElement->base_height)
{
if (footpath_element_is_sloped(tileElement))
{
uint8 slope = footpath_element_get_slope_direction(tileElement);
if (slope != direction)
break;
}
footpath_remove_edges_towards_here(x, y, z1, direction, tileElement, isQueue);
break;
}
if (z0 == tileElement->base_height) {
if (z0 == tileElement->base_height)
{
if (!footpath_element_is_sloped(tileElement))
break;
slope = footpath_element_get_slope_direction(tileElement) ^ 2;
uint8 slope = footpath_element_get_slope_direction(tileElement) ^ 2;
if (slope != direction)
break;

View File

@@ -752,6 +752,11 @@ bool map_is_location_valid(sint32 x, sint32 y)
return false;
}
bool map_is_edge(sint32 x, sint32 y)
{
return (x < 32 || y < 32 || x >= gMapSizeUnits || y >= gMapSizeUnits);
}
bool map_can_build_at(sint32 x, sint32 y, sint32 z)
{
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)

View File

@@ -155,6 +155,7 @@ void map_remove_provisional_elements();
void map_restore_provisional_elements();
void map_update_path_wide_flags();
bool map_is_location_valid(sint32 x, sint32 y);
bool map_is_edge(sint32 x, sint32 y);
bool map_can_build_at(sint32 x, sint32 y, sint32 z);
bool map_is_location_owned(sint32 x, sint32 y, sint32 z);
bool map_is_location_in_park(sint32 x, sint32 y);