Changeset - r17275:7317122af570
[Not reviewed]
master
0 6 0
smatz - 13 years ago 2011-02-08 18:34:13
smatz@openttd.org
(svn r22025) -Fix: verify there is enough space in the pool when creating new pool items while loading old savegames
6 files changed with 38 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/engine.cpp
Show inline comments
 
@@ -497,6 +497,9 @@ void SetCachedEngineCounts()
 
	}
 
}
 

	
 
/**
 
 * Initialise the engine pool with the data from the original vehicles.
 
 */
 
void SetupEngines()
 
{
 
	DeleteWindowByClass(WC_ENGINE_PREVIEW);
 
@@ -506,6 +509,9 @@ void SetupEngines()
 
	const EngineIDMapping *end = _engine_mngr.End();
 
	uint index = 0;
 
	for (const EngineIDMapping *eid = _engine_mngr.Begin(); eid != end; eid++, index++) {
 
		/* Assert is safe; there won't be more than 256 original vehicles
 
		 * in any case, and we just cleaned the pool. */
 
		assert(Engine::CanAllocateItem());
 
		const Engine *e = new Engine(eid->type, eid->internal_id);
 
		assert(e->index == index);
 
	}
src/saveload/afterload.cpp
Show inline comments
 
@@ -782,11 +782,18 @@ bool AfterLoadGame()
 
					case STATION_TRUCK:
 
					case STATION_BUS:
 
						if (IsSavegameVersionBefore(6)) {
 
							/* Before version 5 you could not have more than 250 stations.
 
							 * Version 6 adds large maps, so you could only place 253*253
 
							 * road stops on a map (no freeform edges) = 64009. So, yes
 
							 * someone could in theory create such a full map to trigger
 
							 * this assertion, it's safe to assume that's only something
 
							 * theoretical and does not happen in normal games. */
 
							assert(RoadStop::CanAllocateItem());
 

	
 
							/* From this version on there can be multiple road stops of the
 
							 * same type per station. Convert the existing stops to the new
 
							 * internal data structure. */
 
							RoadStop *rs = new RoadStop(t);
 
							if (rs == NULL) error("Too many road stops in savegame");
 

	
 
							RoadStop **head =
 
								IsTruckStop(t) ? &st->truck_stops : &st->bus_stops;
 
@@ -1928,6 +1935,12 @@ bool AfterLoadGame()
 
					ObjectType type = GetObjectType(t);
 
					int size = type == OBJECT_HQ ? 2 : 1;
 

	
 
					if (!Object::CanAllocateItem()) {
 
						/* Nice... you managed to place 64k lighthouses and
 
						 * antennae on the map... boohoo. */
 
						SlError(STR_ERROR_TOO_MANY_OBJECTS);
 
					}
 

	
 
					Object *o = new Object();
 
					o->location.tile = t;
 
					o->location.w    = size;
 
@@ -2024,6 +2037,10 @@ bool AfterLoadGame()
 
		FOR_ALL_STATIONS(st) {
 
			std::list<Vehicle *>::iterator iter;
 
			for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
 
				/* There are always as many CargoPayments as Vehicles. We need to make the
 
				 * assert() in Pool::GetNew() happy by calling CanAllocateItem(). */
 
				assert_compile(CargoPaymentPool::MAX_SIZE == VehiclePool::MAX_SIZE);
 
				assert(CargoPayment::CanAllocateItem());
 
				Vehicle *v = *iter;
 
				if (v->cargo_payment == NULL) v->cargo_payment = new CargoPayment(v);
 
			}
src/saveload/saveload.cpp
Show inline comments
 
@@ -472,7 +472,7 @@ static void SlNullPointers()
 
 * @note This function does never return as it throws an exception to
 
 *       break out of all the saveload code.
 
 */
 
static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
 
void NORETURN SlError(StringID string, const char *extra_msg)
 
{
 
	/* Distinguish between loading into _load_check_data vs. normal save/load. */
 
	if (_sl.action == SLA_LOAD_CHECK) {
src/saveload/saveload.h
Show inline comments
 
@@ -13,6 +13,7 @@
 
#define SAVELOAD_H
 

	
 
#include "../fileio_type.h"
 
#include "../strings_type.h"
 

	
 
#ifdef SIZE_MAX
 
#undef SIZE_MAX
 
@@ -539,6 +540,7 @@ void SlGlobList(const SaveLoadGlobVarLis
 
void SlArray(void *array, size_t length, VarType conv);
 
void SlObject(void *object, const SaveLoad *sld);
 
bool SlObjectMember(void *object, const SaveLoad *sld);
 
void NORETURN SlError(StringID string, const char *extra_msg = NULL);
 
void NORETURN SlErrorCorrupt(const char *msg);
 

	
 
bool SaveloadCrashWithMissingNewGRFs();
src/saveload/station_sl.cpp
Show inline comments
 
@@ -284,7 +284,11 @@ static void Load_STNS()
 
					/* In old versions, enroute_from used 0xFF as INVALID_STATION */
 
					StationID source = (IsSavegameVersionBefore(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
 

	
 
					/* Don't construct the packet with station here, because that'll fail with old savegames */
 
					/* Make sure we can allocate the CargoPacket. This is safe
 
					 * as there can only be ~64k stations and 32 cargos in these
 
					 * savegame versions. As the CargoPacketPool has more than
 
					 * 16 million entries; it fits by an order of magnitude. */
 
					assert(CargoPacket::CanAllocateItem());
 
					ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share));
 
					SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
 
				}
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -270,6 +270,11 @@ void AfterLoadVehicles(bool part_of_load
 
				if (IsSavegameVersionBefore(105)) { // Pre-105 didn't save an OrderList
 
					if (mapping[v->orders.old] == NULL) {
 
						/* This adds the whole shared vehicle chain for case b */
 

	
 
						/* Creating an OrderList here is safe because the number of vehicles
 
						 * allowed in these savegames matches the number of OrderLists. As
 
						 * such each vehicle can get an OrderList and it will (still) fit. */
 
						assert(OrderList::CanAllocateItem());
 
						v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
 
					} else {
 
						v->orders.list = mapping[v->orders.old];
 
@@ -752,7 +757,7 @@ void Load_VEHS()
 

	
 
		SlObject(v, GetVehicleDescription(vtype));
 

	
 
		if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
 
		if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) {
 
			/* Don't construct the packet with station here, because that'll fail with old savegames */
 
			CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_days, _cargo_source, _cargo_source_xy, _cargo_loaded_at_xy, _cargo_feeder_share);
 
			v->cargo.Append(cp);
0 comments (0 inline, 0 general)