diff options
author | frosch <frosch@openttd.org> | 2009-04-05 12:17:36 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2009-04-05 12:17:36 +0000 |
commit | 3393da4810d64919e825046131f0c95c6819f736 (patch) | |
tree | 1cc4a1ccc51c93195402a4c9330c4b30ef545205 | |
parent | 5551e3d2c628a6dced769801d37b85272cb19e00 (diff) | |
download | openttd-3393da4810d64919e825046131f0c95c6819f736.tar.xz |
(svn r15958) -Fix [FS#2787]: Abort production callback after 0x10000 iterations and show a messagebox blaming the newgrf. (mizipzor)
-rw-r--r-- | src/lang/english.txt | 1 | ||||
-rw-r--r-- | src/newgrf_industries.cpp | 14 |
2 files changed, 15 insertions, 0 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt index d99ad1170..8054bae09 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3171,6 +3171,7 @@ STR_BROKEN_VEHICLE_LENGTH :{WHITE}Train '{ STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:RAW_STRING}' provides incorrect information. STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Cargo/refit information for '{1:ENGINE}' differs from purchase list after construction. This might cause autorenew/-replace to fail refitting correctly. +STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' caused an endless loop in the production callback. STR_LOADGAME_REMOVED_TRAMS :{WHITE}Game was saved in version without tram support. All trams have been removed. diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 88d595893..73397eb7c 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -17,6 +17,8 @@ #include "town.h" #include "company_base.h" #include "command_func.h" +#include "gui.h" +#include "strings_func.h" #include "table/strings.h" @@ -570,6 +572,18 @@ void IndustryProductionCallback(Industry *ind, int reason) object.callback_param2 = reason; for (uint loop = 0;; loop++) { + /* limit the number of calls to break infinite loops. + * 'loop' is provided as 16 bits to the newgrf, so abort when those are exceeded. */ + if (loop >= 0x10000) { + /* display error message */ + SetDParamStr(0, spec->grf_prop.grffile->filename); + SetDParam(1, spec->name); + ShowErrorMessage(STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK, STR_NEWGRF_BUGGY, 0, 0); + + /* abort the function early, this error isn't critical and will allow the game to continue to run */ + break; + } + SB(object.callback_param2, 8, 16, loop); const SpriteGroup *group = Resolve(spec->grf_prop.spritegroup, &object); if (group == NULL || group->type != SGT_INDUSTRY_PRODUCTION) break; |