(svn r11355) -Fix [FS#1377]: loading too many GRFs was not handled gracefully causing crashes and such.
authorrubidium
Mon, 29 Oct 2007 23:02:31 +0000
changeset 7805 7ab20f94cc80
parent 7804 fc2d1522f741
child 7806 2876d9bfa05a
(svn r11355) -Fix [FS#1377]: loading too many GRFs was not handled gracefully causing crashes and such.
src/fileio.cpp
src/fios.h
src/gfxinit.cpp
src/lang/english.txt
src/newgrf.cpp
src/newgrf_config.cpp
src/sound.cpp
--- a/src/fileio.cpp	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/fileio.cpp	Mon Oct 29 23:02:31 2007 +0000
@@ -24,19 +24,18 @@
 /*************************************************/
 
 #define FIO_BUFFER_SIZE 512
-#define MAX_HANDLES 64
 
 struct Fio {
-	byte *buffer, *buffer_end;          ///< position pointer in local buffer and last valid byte of buffer
-	uint32 pos;                         ///< current (system) position in file
-	FILE *cur_fh;                       ///< current file handle
-	const char *filename;               ///< current filename
-	FILE *handles[MAX_HANDLES];         ///< array of file handles we can have open
-	byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
-	const char *filenames[MAX_HANDLES]; ///< array of filenames we (should) have open
+	byte *buffer, *buffer_end;             ///< position pointer in local buffer and last valid byte of buffer
+	uint32 pos;                            ///< current (system) position in file
+	FILE *cur_fh;                          ///< current file handle
+	const char *filename;                  ///< current filename
+	FILE *handles[MAX_FILE_SLOTS];         ///< array of file handles we can have open
+	byte buffer_start[FIO_BUFFER_SIZE];    ///< local buffer when read from file
+	const char *filenames[MAX_FILE_SLOTS]; ///< array of filenames we (should) have open
 #if defined(LIMITED_FDS)
-	uint open_handles;                  ///< current amount of open handles
-	uint usage_count[MAX_HANDLES];      ///< count how many times this file has been opened
+	uint open_handles;                     ///< current amount of open handles
+	uint usage_count[MAX_FILE_SLOTS];      ///< count how many times this file has been opened
 #endif /* LIMITED_FDS */
 };
 
--- a/src/fios.h	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/fios.h	Mon Oct 29 23:02:31 2007 +0000
@@ -5,6 +5,24 @@
 #ifndef FIOS_H
 #define FIOS_H
 
+enum {
+	/**
+	 * Slot used for the GRF scanning and such. This slot cannot be reused
+	 * as it will otherwise cause issues when pressing "rescan directories".
+	 * It can furthermore not be larger than LAST_GRF_SLOT as that complicates
+	 * the testing for "too much NewGRFs".
+	 */
+	CONFIG_SLOT    =  0,
+	/** Slot for the sound. */
+	SOUND_SLOT     =  1,
+	/** First slot useable for (New)GRFs used during the game. */
+	FIRST_GRF_SLOT =  2,
+	/** Last slot useable for (New)GRFs used during the game. */
+	LAST_GRF_SLOT  = 63,
+	/** Maximum number of slots. */
+	MAX_FILE_SLOTS = 64
+};
+
 /* Deals with finding savegames */
 struct FiosItem {
 	byte type;
--- a/src/gfxinit.cpp	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/gfxinit.cpp	Mon Oct 29 23:02:31 2007 +0000
@@ -11,6 +11,7 @@
 #include "spritecache.h"
 #include "table/sprites.h"
 #include "fileio.h"
+#include "fios.h"
 #include "string.h"
 #include "newgrf.h"
 #include "md5.h"
@@ -333,16 +334,16 @@
 {
 	const FileList* files = _use_dos_palette ? &files_dos : &files_win;
 	uint load_index;
-	uint i;
+	uint i = FIRST_GRF_SLOT;
 
-	LoadGrfIndexed(files->basic[0].filename, trg1idx, 0);
+	LoadGrfIndexed(files->basic[0].filename, trg1idx, i++);
 	DupSprite(  2, 130); // non-breaking space medium
 	DupSprite(226, 354); // non-breaking space tiny
 	DupSprite(450, 578); // non-breaking space large
 	load_index = 4793;
 
-	for (i = 1; files->basic[i].filename != NULL; i++) {
-		load_index += LoadGrfFile(files->basic[i].filename, load_index, i);
+	for (uint j = 1; files->basic[j].filename != NULL; j++) {
+		load_index += LoadGrfFile(files->basic[j].filename, load_index, i++);
 	}
 
 	/* Load additional sprites for climates other than temperate */
--- a/src/lang/english.txt	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/lang/english.txt	Mon Oct 29 23:02:31 2007 +0000
@@ -3077,6 +3077,7 @@
 STR_NEWGRF_ERROR_LOAD_AFTER                                     :{STRING} must be loaded after {STRING}.
 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER                            :{STRING} requires OpenTTD version {STRING} or better.
 STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE                          :the GRF file it was designed to translate
+STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED                        :Too many NewGRFs are loaded.
 
 STR_NEWGRF_ADD                                                  :{BLACK}Add
 STR_NEWGRF_ADD_TIP                                              :{BLACK}Add a NewGRF file to the list
--- a/src/newgrf.cpp	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/newgrf.cpp	Mon Oct 29 23:02:31 2007 +0000
@@ -47,6 +47,7 @@
 #include "newgrf_industries.h"
 #include "table/landscape_sprite.h"
 #include "gfxinit.h"
+#include "fios.h"
 
 /* TTDPatch extended GRF format codec
  * (c) Petr Baudis 2004 (GPL'd)
@@ -5421,6 +5422,15 @@
 		if (stage == GLS_ACTIVATION && config->status != GCS_INITIALISED) return;
 	}
 
+	if (file_index > LAST_GRF_SLOT) {
+		DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
+		config->status = GCS_DISABLED;
+		config->error  = CallocT<GRFError>(1);
+		config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
+		config->error->message  = STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED;
+		return;
+	}
+
 	FioOpenFile(file_index, filename);
 	_file_index = file_index; // XXX
 
--- a/src/newgrf_config.cpp	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/newgrf_config.cpp	Mon Oct 29 23:02:31 2007 +0000
@@ -66,9 +66,7 @@
 	}
 
 	/* Find and load the Action 8 information */
-	/* 62 is the last file slot before sample.cat.
-	 * Should perhaps be some "don't care" value */
-	LoadNewGRFFile(config, 62, GLS_FILESCAN);
+	LoadNewGRFFile(config, CONFIG_SLOT, GLS_FILESCAN);
 
 	/* Skip if the grfid is 0 (not read) or 0xFFFFFFFF (ttdp system grf) */
 	if (config->grfid == 0 || config->grfid == 0xFFFFFFFF) return false;
--- a/src/sound.cpp	Mon Oct 29 22:30:54 2007 +0000
+++ b/src/sound.cpp	Mon Oct 29 23:02:31 2007 +0000
@@ -15,11 +15,11 @@
 #include "fileio.h"
 #include "newgrf_sound.h"
 #include "helpers.hpp"
+#include "fios.h"
 
 static uint _file_count;
 static FileEntry *_files;
 
-#define SOUND_SLOT 63
 // Number of levels of panning per side
 #define PANNING_LEVELS 16