diff options
author | rubidium <rubidium@openttd.org> | 2009-09-21 18:31:47 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2009-09-21 18:31:47 +0000 |
commit | 3dd202ba1c15bb5e1bac3ab21eed7f63435a88bb (patch) | |
tree | cc79e3432f44c4aa40e68adfc07e30d559557bb8 | |
parent | 9da24054b2f167260fed5471f78fa56ce7b417bc (diff) | |
download | openttd-3dd202ba1c15bb5e1bac3ab21eed7f63435a88bb.tar.xz |
(svn r17605) -Fix [FS#3218]: [NewGRF] Crash when defining the same tile in a tile layout twice
-rw-r--r-- | src/newgrf.cpp | 31 |
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; |