(svn r3151) - Fix: showing the highscore might crash the game with an invalid string message in the case when a highscore file was used before certain strings were added.
- Codechange: protect _endgame_perf_titles from out-of-bounds access.
This commit is contained in:
		
							
								
								
									
										4
									
								
								player.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								player.h
									
									
									
									
									
								
							@@ -252,8 +252,8 @@ static inline RailType GetBestRailtype(const Player* p)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct HighScore {
 | 
					typedef struct HighScore {
 | 
				
			||||||
	char company[100];
 | 
						char company[100];
 | 
				
			||||||
	StringID title;
 | 
						StringID title; // NO_SAVE, has troubles with changing string-numbers.
 | 
				
			||||||
	uint16 score;
 | 
						uint16 score;   // do NOT change type, will break hs.dat
 | 
				
			||||||
} HighScore;
 | 
					} HighScore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
 | 
					VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								players.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								players.c
									
									
									
									
									
								
							@@ -897,7 +897,7 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const StringID _endgame_performance_titles[16] = {
 | 
					static const StringID _endgame_perf_titles[16] = {
 | 
				
			||||||
	STR_0213_BUSINESSMAN,
 | 
						STR_0213_BUSINESSMAN,
 | 
				
			||||||
	STR_0213_BUSINESSMAN,
 | 
						STR_0213_BUSINESSMAN,
 | 
				
			||||||
	STR_0213_BUSINESSMAN,
 | 
						STR_0213_BUSINESSMAN,
 | 
				
			||||||
@@ -918,7 +918,10 @@ static const StringID _endgame_performance_titles[16] = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
StringID EndGameGetPerformanceTitleFromValue(uint value)
 | 
					StringID EndGameGetPerformanceTitleFromValue(uint value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return _endgame_performance_titles[minu(value, 1000) >> 6];
 | 
						value = minu(value, 1000) >> 6;
 | 
				
			||||||
 | 
						if (value >= lengthof(_endgame_perf_titles)) value = lengthof(_endgame_perf_titles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return _endgame_perf_titles[value];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return true if any cheat has been used, false otherwise */
 | 
					/* Return true if any cheat has been used, false otherwise */
 | 
				
			||||||
@@ -1029,7 +1032,7 @@ int8 SaveHighScoreValueNetwork(void)
 | 
				
			|||||||
/* Save HighScore table to file */
 | 
					/* Save HighScore table to file */
 | 
				
			||||||
void SaveToHighScore(void)
 | 
					void SaveToHighScore(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILE *fp = fopen(_highscore_file, "w");
 | 
						FILE *fp = fopen(_highscore_file, "wb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fp != NULL) {
 | 
						if (fp != NULL) {
 | 
				
			||||||
		uint i;
 | 
							uint i;
 | 
				
			||||||
@@ -1043,7 +1046,7 @@ void SaveToHighScore(void)
 | 
				
			|||||||
				fwrite(&length, sizeof(length), 1, fp); // write away string length
 | 
									fwrite(&length, sizeof(length), 1, fp); // write away string length
 | 
				
			||||||
				fwrite(hs->company, length, 1, fp);
 | 
									fwrite(hs->company, length, 1, fp);
 | 
				
			||||||
				fwrite(&hs->score, sizeof(hs->score), 1, fp);
 | 
									fwrite(&hs->score, sizeof(hs->score), 1, fp);
 | 
				
			||||||
				fwrite(&hs->title, sizeof(hs->title), 1, fp);
 | 
									fwrite("", 2, 1, fp); /* XXX - placeholder for hs->title, not saved anymore; compatibility */
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fclose(fp);
 | 
							fclose(fp);
 | 
				
			||||||
@@ -1053,7 +1056,7 @@ void SaveToHighScore(void)
 | 
				
			|||||||
/* Initialize the highscore table to 0 and if any file exists, load in values */
 | 
					/* Initialize the highscore table to 0 and if any file exists, load in values */
 | 
				
			||||||
void LoadFromHighScore(void)
 | 
					void LoadFromHighScore(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILE *fp = fopen(_highscore_file, "r");
 | 
						FILE *fp = fopen(_highscore_file, "rb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(_highscore_table, 0, sizeof(_highscore_table));
 | 
						memset(_highscore_table, 0, sizeof(_highscore_table));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1068,7 +1071,8 @@ void LoadFromHighScore(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				fread(hs->company, 1, length, fp);
 | 
									fread(hs->company, 1, length, fp);
 | 
				
			||||||
				fread(&hs->score, sizeof(hs->score), 1, fp);
 | 
									fread(&hs->score, sizeof(hs->score), 1, fp);
 | 
				
			||||||
				fread(&hs->title, sizeof(hs->title), 1, fp);
 | 
									fseek(fp, 2, SEEK_CUR); /* XXX - placeholder for hs->title, not saved anymore; compatibility */
 | 
				
			||||||
 | 
									hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fclose(fp);
 | 
							fclose(fp);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user