Changeset - r11582:3a0dfd7221e5
[Not reviewed]
master
0 2 0
frosch - 15 years ago 2009-04-05 12:17:36
frosch@openttd.org
(svn r15958) -Fix [FS#2787]: Abort production callback after 0x10000 iterations and show a messagebox blaming the newgrf. (mizipzor)
2 files changed with 15 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -3171,6 +3171,7 @@ STR_BROKEN_VEHICLE_LENGTH               
 

	
 
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.
 

	
src/newgrf_industries.cpp
Show inline comments
 
@@ -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
 
	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;
0 comments (0 inline, 0 general)