summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-12-17 23:26:25 +0000
committeryexo <yexo@openttd.org>2009-12-17 23:26:25 +0000
commit8c737964ecbf1e86d8563110c471cdba1105c2ca (patch)
treeb899cd8c227f591c7d08e3870e66044a1d9001c6
parent2fd1ccf2890da0bb65e874f5957ea38ab8212794 (diff)
downloadopenttd-8c737964ecbf1e86d8563110c471cdba1105c2ca.tar.xz
(svn r18527) -Fix: an industry newgrf that defined a too small size for action0 prop 0A could cause a crash
-rw-r--r--src/newgrf.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index ab03023e6..f30b2ef97 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2249,14 +2249,26 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
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) {