mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 14:24:33 +01:00
Fix #7052: Infinite loops occur in track circuit iteration
This commit is contained in:
@@ -818,7 +818,7 @@ sint32 ride_find_track_gap(rct_xy_element *input, rct_xy_element *output)
|
||||
if (w != nullptr && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && _currentRideIndex == rideIndex)
|
||||
ride_construction_invalidate_current_track();
|
||||
|
||||
bool counter = true;
|
||||
bool moveSlowIt = true;
|
||||
track_circuit_iterator_begin(&it, *input);
|
||||
slowIt = it;
|
||||
while (track_circuit_iterator_next(&it)) {
|
||||
@@ -827,13 +827,12 @@ sint32 ride_find_track_gap(rct_xy_element *input, rct_xy_element *output)
|
||||
return 1;
|
||||
}
|
||||
//#2081: prevent an infinite loop
|
||||
counter = !counter;
|
||||
if (counter) {
|
||||
moveSlowIt = !moveSlowIt;
|
||||
if (moveSlowIt)
|
||||
{
|
||||
track_circuit_iterator_next(&slowIt);
|
||||
if (slowIt.currentZ == it.currentZ &&
|
||||
slowIt.currentDirection == it.currentDirection &&
|
||||
slowIt.current.x == it.current.x &&
|
||||
slowIt.current.y == it.current.y) {
|
||||
if (track_circuit_iterators_match(&it, &slowIt))
|
||||
{
|
||||
*output = it.current;
|
||||
return 1;
|
||||
}
|
||||
@@ -4172,14 +4171,28 @@ static bool ride_check_track_contains_inversions(rct_xy_element *input, rct_xy_e
|
||||
ride_construction_invalidate_current_track();
|
||||
}
|
||||
|
||||
track_circuit_iterator it;
|
||||
bool moveSlowIt = true;
|
||||
track_circuit_iterator it, slowIt;
|
||||
track_circuit_iterator_begin(&it, *input);
|
||||
slowIt = it;
|
||||
|
||||
while (track_circuit_iterator_next(&it)) {
|
||||
sint32 trackType = track_element_get_type(it.current.element);
|
||||
if (TrackFlags[trackType] & TRACK_ELEM_FLAG_INVERSION_TO_NORMAL) {
|
||||
*output = it.current;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prevents infinite loops
|
||||
moveSlowIt = !moveSlowIt;
|
||||
if (moveSlowIt)
|
||||
{
|
||||
track_circuit_iterator_next(&slowIt);
|
||||
if (track_circuit_iterators_match(&it, &slowIt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -4203,14 +4216,28 @@ static bool ride_check_track_contains_banked(rct_xy_element *input, rct_xy_eleme
|
||||
ride_construction_invalidate_current_track();
|
||||
}
|
||||
|
||||
track_circuit_iterator it;
|
||||
bool moveSlowIt = true;
|
||||
track_circuit_iterator it, slowIt;
|
||||
track_circuit_iterator_begin(&it, *input);
|
||||
slowIt = it;
|
||||
|
||||
while (track_circuit_iterator_next(&it)) {
|
||||
sint32 trackType = track_element_get_type(output->element);
|
||||
if (TrackFlags[trackType] & TRACK_ELEM_FLAG_BANKED) {
|
||||
*output = it.current;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prevents infinite loops
|
||||
moveSlowIt = !moveSlowIt;
|
||||
if (moveSlowIt)
|
||||
{
|
||||
track_circuit_iterator_next(&slowIt);
|
||||
if (track_circuit_iterators_match(&it, &slowIt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -6991,7 +7018,7 @@ static sint32 ride_get_track_length(Ride * ride)
|
||||
{
|
||||
rct_window * w;
|
||||
rct_tile_element * tileElement = nullptr;
|
||||
track_circuit_iterator it;
|
||||
track_circuit_iterator it, slowIt;
|
||||
sint32 x = 0, y = 0, z, trackType, rideIndex, result;
|
||||
bool foundTrack = false;
|
||||
|
||||
@@ -7033,12 +7060,23 @@ static sint32 ride_get_track_length(Ride * ride)
|
||||
ride_construction_invalidate_current_track();
|
||||
}
|
||||
|
||||
bool moveSlowIt = true;
|
||||
result = 0;
|
||||
track_circuit_iterator_begin(&it, {x, y, tileElement});
|
||||
slowIt = it;
|
||||
while (track_circuit_iterator_next(&it))
|
||||
{
|
||||
trackType = track_element_get_type(it.current.element);
|
||||
result += TrackPieceLengths[trackType];
|
||||
|
||||
if (moveSlowIt)
|
||||
{
|
||||
track_circuit_iterator_next(&slowIt);
|
||||
if (track_circuit_iterators_match(&it, &slowIt))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2402,6 +2402,14 @@ bool track_circuit_iterator_next(track_circuit_iterator * it)
|
||||
}
|
||||
}
|
||||
|
||||
bool track_circuit_iterators_match(const track_circuit_iterator * firstIt, const track_circuit_iterator * secondIt)
|
||||
{
|
||||
return (firstIt->currentZ == secondIt->currentZ &&
|
||||
firstIt->currentDirection == secondIt->currentDirection &&
|
||||
firstIt->current.x == secondIt->current.x &&
|
||||
firstIt->current.y == secondIt->current.y);
|
||||
}
|
||||
|
||||
void track_get_back(rct_xy_element * input, rct_xy_element * output)
|
||||
{
|
||||
rct_xy_element lastTrack;
|
||||
|
||||
@@ -537,6 +537,7 @@ const rct_track_coordinates * get_track_coord_from_ride(Ride * ride, sint32 trac
|
||||
void track_circuit_iterator_begin(track_circuit_iterator * it, rct_xy_element first);
|
||||
bool track_circuit_iterator_previous(track_circuit_iterator * it);
|
||||
bool track_circuit_iterator_next(track_circuit_iterator * it);
|
||||
bool track_circuit_iterators_match(const track_circuit_iterator * firstIt, const track_circuit_iterator * secondIt);
|
||||
|
||||
void track_get_back(rct_xy_element * input, rct_xy_element * output);
|
||||
void track_get_front(rct_xy_element * input, rct_xy_element * output);
|
||||
|
||||
Reference in New Issue
Block a user