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
 
@@ -494,21 +494,27 @@ void SetCachedEngineCounts()
 
		assert(v->owner == g->owner);
 

	
 
		g->num_engines[v->engine_type]++;
 
	}
 
}
 

	
 
/**
 
 * Initialise the engine pool with the data from the original vehicles.
 
 */
 
void SetupEngines()
 
{
 
	DeleteWindowByClass(WC_ENGINE_PREVIEW);
 
	_engine_pool.CleanPool();
 

	
 
	assert(_engine_mngr.Length() >= _engine_mngr.NUM_DEFAULT_ENGINES);
 
	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);
 
	}
 

	
 
	_introduced_railtypes = 0;
 
}
src/saveload/afterload.cpp
Show inline comments
 
@@ -779,17 +779,24 @@ bool AfterLoadGame()
 
				Station *st = Station::From(bst);
 

	
 
				switch (GetStationType(t)) {
 
					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;
 
							*head = rs;
 
						}
 
						break;
 
@@ -1925,12 +1932,18 @@ bool AfterLoadGame()
 

	
 
				if (offset == 0) {
 
					/* No offset, so make the object. */
 
					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;
 
					o->location.h    = size;
 
					o->build_date    = _date;
 
					o->town          = type == OBJECT_STATUE ? Town::Get(_m[t].m2) : CalcClosestTownFromTile(t, UINT_MAX);
 
@@ -2021,12 +2034,16 @@ bool AfterLoadGame()
 
		 * add cargopayment for the vehicles that don't have it.
 
		 */
 
		Station *st;
 
		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
 
@@ -469,13 +469,13 @@ static void SlNullPointers()
 
 * up the mess of a partial savegame load.
 
 * @param string The translatable error message to show.
 
 * @param extra_msg An extra error message coming from one of the APIs.
 
 * @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) {
 
		_load_check_data.error = string;
 
		free(_load_check_data.error_data);
 
		_load_check_data.error_data = (extra_msg == NULL) ? NULL : strdup(extra_msg);
src/saveload/saveload.h
Show inline comments
 
@@ -10,12 +10,13 @@
 
/** @file saveload.h Functions/types related to saving and loading games. */
 

	
 
#ifndef SAVELOAD_H
 
#define SAVELOAD_H
 

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

	
 
#ifdef SIZE_MAX
 
#undef SIZE_MAX
 
#endif
 

	
 
#define SIZE_MAX ((size_t)-1)
 
@@ -536,12 +537,13 @@ byte SlReadByte();
 
void SlWriteByte(byte b);
 

	
 
void SlGlobList(const SaveLoadGlobVarList *sldg);
 
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();
 

	
 
extern char _savegame_format[8];
 
extern bool _do_autosave;
src/saveload/station_sl.cpp
Show inline comments
 
@@ -281,13 +281,17 @@ static void Load_STNS()
 
			if (IsSavegameVersionBefore(68)) {
 
				SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
 
				if (GB(_waiting_acceptance, 0, 12) != 0) {
 
					/* 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
 
@@ -267,12 +267,17 @@ void AfterLoadVehicles(bool part_of_load
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->orders.old != NULL) {
 
				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];
 
						/* For old games (case a) we must create the shared vehicle chain */
 
						if (IsSavegameVersionBefore(5, 2)) {
 
							v->AddToShared(v->orders.list->GetFirstSharedVehicle());
 
@@ -749,13 +754,13 @@ void Load_VEHS()
 
			case VEH_INVALID: // Savegame shouldn't contain invalid vehicles
 
			default: SlErrorCorrupt("Invalid vehicle type");
 
		}
 

	
 
		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);
 
		}
 

	
 
		/* Old savegames used 'last_station_visited = 0xFF' */
0 comments (0 inline, 0 general)