Mercurial > hg > openttd
changeset 13985:c895195a6748 draft
(svn r18527) -Fix: an industry newgrf that defined a too small size for action0 prop 0A could cause a crash
author | yexo <yexo@openttd.org> |
---|---|
date | Thu, 17 Dec 2009 23:26:25 +0000 |
parents | acf0c4d02a68 |
children | 698552f00a71 |
files | src/newgrf.cpp |
diffstat | 1 files changed, 16 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2249,14 +2249,26 @@ case 0x0A: { // Set industry layout(s) indsp->num_table = grf_load_byte(&buf); // Number of layaouts - uint32 defsize = grf_load_dword(&buf); // Total size of the definition + /* We read the total size in bytes, but we can't rely on the + * newgrf to provide a sane value. First assume the value is + * sane but later on we make sure we enlarge the array if the + * newgrf contains more data. Each tile uses either 3 or 5 + * bytes, so to play it safe we assume 3. */ + uint32 def_num_tiles = grf_load_dword(&buf) / 3 + 1; IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(indsp->num_table); // Table with tiles to compose an industry - IndustryTileTable *itt = CallocT<IndustryTileTable>(defsize); // Temporary array to read the tile layouts from the GRF - int size; + IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF + uint size; const IndustryTileTable *copy_from; for (byte j = 0; j < indsp->num_table; j++) { - for (int k = 0;; k++) { + for (uint k = 0;; k++) { + if (k >= def_num_tiles) { + grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid); + /* Size reported by newgrf was not big enough so enlarge the array. */ + def_num_tiles *= 2; + itt = ReallocT<IndustryTileTable>(itt, def_num_tiles); + } + itt[k].ti.x = grf_load_byte(&buf); // Offsets from northermost tile if (itt[k].ti.x == 0xFE && k == 0) {