mirror of https://github.com/OpenTTD/OpenTTD
(svn r7582) -Fix (r7490): appending static GRFs to the list of to-be loaded GRF for a game could result in duplicate GRFs in that list, which can cause a segmentation fault while loading the GRFs.
parent
1d6bd64c19
commit
8a812544ec
|
@ -131,6 +131,50 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src)
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes duplicates from lists of GRFConfigs. These duplicates
|
||||||
|
* are introduced when the _grfconfig_static GRFs are appended
|
||||||
|
* to the _grfconfig on a newgame or savegame. As the parameters
|
||||||
|
* of the static GRFs could be different that the parameters of
|
||||||
|
* the ones used non-statically. This can result in desyncs in
|
||||||
|
* multiplayers, so the duplicate static GRFs have to be removed.
|
||||||
|
*
|
||||||
|
* This function _assumes_ that all static GRFs are placed after
|
||||||
|
* the non-static GRFs.
|
||||||
|
*
|
||||||
|
* @param list the list to remove the duplicates from
|
||||||
|
*/
|
||||||
|
static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list)
|
||||||
|
{
|
||||||
|
GRFConfig *prev;
|
||||||
|
GRFConfig *cur;
|
||||||
|
|
||||||
|
if (list == NULL) return;
|
||||||
|
|
||||||
|
for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) {
|
||||||
|
if (cur->grfid != list->grfid) continue;
|
||||||
|
assert(HASBIT(cur->flags, GCF_STATIC));
|
||||||
|
prev->next = cur->next;
|
||||||
|
ClearGRFConfig(&cur);
|
||||||
|
cur = prev; // Just go back one so it continues as normal later on
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveDuplicatesFromGRFConfigList(list->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the static GRFs to a list of GRFs
|
||||||
|
* @param dst the head of the list to add to
|
||||||
|
*/
|
||||||
|
void AppendStaticGRFConfigs(GRFConfig **dst)
|
||||||
|
{
|
||||||
|
GRFConfig **tail = dst;
|
||||||
|
while (*tail != NULL) tail = &(*tail)->next;
|
||||||
|
|
||||||
|
CopyGRFConfigList(tail, _grfconfig_static);
|
||||||
|
RemoveDuplicatesFromGRFConfigList(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset the current GRF Config to either blank or newgame settings */
|
/* Reset the current GRF Config to either blank or newgame settings */
|
||||||
void ResetGRFConfig(bool defaults)
|
void ResetGRFConfig(bool defaults)
|
||||||
|
@ -138,7 +182,7 @@ void ResetGRFConfig(bool defaults)
|
||||||
GRFConfig **c = &_grfconfig;
|
GRFConfig **c = &_grfconfig;
|
||||||
|
|
||||||
if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame);
|
if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame);
|
||||||
CopyGRFConfigList(c, _grfconfig_static);
|
AppendStaticGRFConfigs(&_grfconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,6 +444,7 @@ static void Load_NGRF(void)
|
||||||
|
|
||||||
ClearGRFConfigList(&_grfconfig);
|
ClearGRFConfigList(&_grfconfig);
|
||||||
_grfconfig = first;
|
_grfconfig = first;
|
||||||
|
AppendStaticGRFConfigs(&_grfconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChunkHandler _newgrf_chunk_handlers[] = {
|
const ChunkHandler _newgrf_chunk_handlers[] = {
|
||||||
|
|
|
@ -44,6 +44,7 @@ void ScanNewGRFFiles(void);
|
||||||
const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
|
const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
|
||||||
GRFConfig *GetGRFConfig(uint32 grfid);
|
GRFConfig *GetGRFConfig(uint32 grfid);
|
||||||
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src);
|
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src);
|
||||||
|
void AppendStaticGRFConfigs(GRFConfig **dst);
|
||||||
void ClearGRFConfig(GRFConfig **config);
|
void ClearGRFConfig(GRFConfig **config);
|
||||||
void ClearGRFConfigList(GRFConfig **config);
|
void ClearGRFConfigList(GRFConfig **config);
|
||||||
void ResetGRFConfig(bool defaults);
|
void ResetGRFConfig(bool defaults);
|
||||||
|
|
Loading…
Reference in New Issue