Changeset - r20058:431b83660079
[Not reviewed]
master
0 1 0
rubidium - 11 years ago 2013-02-17 20:16:49
rubidium@openttd.org
(svn r25016) -Fix [FS#5476]: integer overflow in UpdateStationRating (fonsinchen)
1 file changed with 3 insertions and 1 deletions:
0 comments (0 inline, 0 general)
src/station_cmd.cpp
Show inline comments
 
@@ -3286,49 +3286,51 @@ static void UpdateStationRating(Station 
 
				if (rating <= 127 && waiting != 0) {
 
					uint32 r = Random();
 
					if (rating <= (int)GB(r, 0, 7)) {
 
						/* Need to have int, otherwise it will just overflow etc. */
 
						waiting = max((int)waiting - (int)GB(r, 8, 2) - 1, 0);
 
						waiting_changed = true;
 
					}
 
				}
 

	
 
				/* At some point we really must cap the cargo. Previously this
 
				 * was a strict 4095, but now we'll have a less strict, but
 
				 * increasingly aggressive truncation of the amount of cargo. */
 
				static const uint WAITING_CARGO_THRESHOLD  = 1 << 12;
 
				static const uint WAITING_CARGO_CUT_FACTOR = 1 <<  6;
 
				static const uint MAX_WAITING_CARGO        = 1 << 15;
 

	
 
				if (waiting > WAITING_CARGO_THRESHOLD) {
 
					uint difference = waiting - WAITING_CARGO_THRESHOLD;
 
					waiting -= (difference / WAITING_CARGO_CUT_FACTOR);
 

	
 
					waiting = min(waiting, MAX_WAITING_CARGO);
 
					waiting_changed = true;
 
				}
 

	
 
				if (waiting_changed) ge->cargo.Truncate(ge->cargo.Count() - waiting);
 
				if (waiting_changed && waiting < ge->cargo.Count()) {
 
					ge->cargo.Truncate(ge->cargo.Count() - waiting);
 
				}
 
			}
 
		}
 
	}
 

	
 
	StationID index = st->index;
 
	if (waiting_changed) {
 
		SetWindowDirty(WC_STATION_VIEW, index); // update whole window
 
	} else {
 
		SetWindowWidgetDirty(WC_STATION_VIEW, index, WID_SV_ACCEPT_RATING_LIST); // update only ratings list
 
	}
 
}
 

	
 
/* called for every station each tick */
 
static void StationHandleSmallTick(BaseStation *st)
 
{
 
	if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return;
 

	
 
	byte b = st->delete_ctr + 1;
 
	if (b >= STATION_RATING_TICKS) b = 0;
 
	st->delete_ctr = b;
 

	
 
	if (b == 0) UpdateStationRating(Station::From(st));
 
}
 

	
0 comments (0 inline, 0 general)