mirror of https://github.com/OpenTTD/OpenTTD
(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.release/0.4.5
parent
8bcfa23d29
commit
f816b74536
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);
|
||||||
|
|
Loading…
Reference in New Issue