summaryrefslogtreecommitdiff
path: root/src/newgrf.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-09-21 18:31:47 +0000
committerrubidium <rubidium@openttd.org>2009-09-21 18:31:47 +0000
commit3dd202ba1c15bb5e1bac3ab21eed7f63435a88bb (patch)
treecc79e3432f44c4aa40e68adfc07e30d559557bb8 /src/newgrf.cpp
parent9da24054b2f167260fed5471f78fa56ce7b417bc (diff)
downloadopenttd-3dd202ba1c15bb5e1bac3ab21eed7f63435a88bb.tar.xz
(svn r17605) -Fix [FS#3218]: [NewGRF] Crash when defining the same tile in a tile layout twice
Diffstat (limited to 'src/newgrf.cpp')
-rw-r--r--src/newgrf.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 01e080b74..58773ec7b 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2148,6 +2148,25 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr
return ret;
}
+/**
+ * Validate the industry layout; e.g. to prevent duplicate tiles.
+ * @param layout the layout to check
+ * @param size the size of the layout
+ * @return true if the layout is deemed valid
+ */
+static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
+{
+ for (int i = 0; i < size - 1; i++) {
+ for (int j = i + 1; j < size; j++) {
+ if (layout[i].ti.x == layout[j].ti.x &&
+ layout[i].ti.y == layout[j].ti.y) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len)
{
byte *buf = *bufp;
@@ -2279,8 +2298,16 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
}
}
- tile_table[j] = CallocT<IndustryTileTable>(size);
- memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
+
+ if (!ValidateIndustryLayout(copy_from, size)) {
+ /* The industry layout was not valid, so skip this one. */
+ grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
+ indsp->num_table--;
+ j--;
+ } else {
+ tile_table[j] = CallocT<IndustryTileTable>(size);
+ memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
+ }
}
/* Install final layout construction in the industry spec */
indsp->table = tile_table;