(svn r17605) -Fix [FS#3218]: [NewGRF] Crash when defining the same tile in a tile layout twice

This commit is contained in:
rubidium 2009-09-21 18:31:47 +00:00
parent 9da24054b2
commit 3dd202ba1c
1 changed files with 29 additions and 2 deletions

View File

@ -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;