(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.
authorDarkvater
Mon, 07 Nov 2005 13:30:43 +0000
changeset 2613 b008d366ed8a
parent 2612 744aef3af72f
child 2614 0e69ad985358
(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.
player.h
players.c
--- a/player.h	Mon Nov 07 13:02:33 2005 +0000
+++ b/player.h	Mon Nov 07 13:30:43 2005 +0000
@@ -252,8 +252,8 @@
 
 typedef struct HighScore {
 	char company[100];
-	StringID title;
-	uint16 score;
+	StringID title; // NO_SAVE, has troubles with changing string-numbers.
+	uint16 score;   // do NOT change type, will break hs.dat
 } HighScore;
 
 VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5
--- a/players.c	Mon Nov 07 13:02:33 2005 +0000
+++ b/players.c	Mon Nov 07 13:30:43 2005 +0000
@@ -897,7 +897,7 @@
 	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,
@@ -918,7 +918,10 @@
 
 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 */
@@ -1029,7 +1032,7 @@
 /* Save HighScore table to file */
 void SaveToHighScore(void)
 {
-	FILE *fp = fopen(_highscore_file, "w");
+	FILE *fp = fopen(_highscore_file, "wb");
 
 	if (fp != NULL) {
 		uint i;
@@ -1043,7 +1046,7 @@
 				fwrite(&length, sizeof(length), 1, fp); // write away string length
 				fwrite(hs->company, length, 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);
@@ -1053,7 +1056,7 @@
 /* Initialize the highscore table to 0 and if any file exists, load in values */
 void LoadFromHighScore(void)
 {
-	FILE *fp = fopen(_highscore_file, "r");
+	FILE *fp = fopen(_highscore_file, "rb");
 
 	memset(_highscore_table, 0, sizeof(_highscore_table));
 
@@ -1068,7 +1071,8 @@
 
 				fread(hs->company, 1, length, 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);