Added a simple checksum for stage metadata to fail quickly if garbage is detected
This commit is contained in:
parent
f2386657f5
commit
b0da5a407c
2 changed files with 30 additions and 4 deletions
28
src/replay.c
28
src/replay.c
|
@ -128,6 +128,26 @@ int replay_write_stage_event(ReplayEvent *evt, SDL_RWops *file) {
|
|||
return True;
|
||||
}
|
||||
|
||||
uint32_t replay_calc_stageinfo_checksum(ReplayStage *stg) {
|
||||
uint32_t cs = 0;
|
||||
cs += stg->stage;
|
||||
cs += stg->seed;
|
||||
cs += stg->diff;
|
||||
cs += stg->points;
|
||||
cs += stg->plr_char;
|
||||
cs += stg->plr_shot;
|
||||
cs += stg->plr_pos_x;
|
||||
cs += stg->plr_pos_y;
|
||||
cs += stg->plr_focus;
|
||||
cs += stg->plr_fire;
|
||||
cs += stg->plr_power;
|
||||
cs += stg->plr_lifes;
|
||||
cs += stg->plr_bombs;
|
||||
cs += stg->plr_moveflags;
|
||||
cs += stg->ecount;
|
||||
return cs;
|
||||
}
|
||||
|
||||
int replay_write_stage(ReplayStage *stg, SDL_RWops *file) {
|
||||
int i;
|
||||
|
||||
|
@ -146,6 +166,7 @@ int replay_write_stage(ReplayStage *stg, SDL_RWops *file) {
|
|||
SDL_WriteU8(file, stg->plr_bombs);
|
||||
SDL_WriteU8(file, stg->plr_moveflags);
|
||||
SDL_WriteLE16(file, stg->ecount);
|
||||
SDL_WriteLE32(file, 1 + ~replay_calc_stageinfo_checksum(stg));
|
||||
|
||||
for(i = 0; i < stg->ecount; ++i) {
|
||||
if(!replay_write_stage_event(&stg->events[i], file)) {
|
||||
|
@ -261,6 +282,11 @@ int replay_read(Replay *rpy, SDL_RWops *file) {
|
|||
CHECKPROP(stg->plr_moveflags = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->ecount = SDL_ReadLE16(file), u);
|
||||
|
||||
if(replay_calc_stageinfo_checksum(stg) + SDL_ReadLE32(file)) {
|
||||
warnx("replay_read(): stageinfo is corrupt");
|
||||
return False;
|
||||
}
|
||||
|
||||
if(!stg->ecount) {
|
||||
warnx("replay_read(): no events in stage");
|
||||
return False;
|
||||
|
@ -423,7 +449,7 @@ int replay_test(void) {
|
|||
errx(-1, "Succeeded loading garbage data as a replay... that shouldn't happen");
|
||||
}
|
||||
|
||||
replay_destroy(rpy);
|
||||
replay_destroy(&rpy);
|
||||
free(buf);
|
||||
return 1;
|
||||
#else
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#define REPLAY_ALLOC_INITIAL 256
|
||||
#define REPLAY_EXTENSION "tsr"
|
||||
#define REPLAY_STRUCT_VERSION 2
|
||||
#define REPLAY_STRUCT_VERSION 3
|
||||
#define REPLAY_USELESS_BYTE 0x69
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -46,11 +46,11 @@ typedef struct ReplayStage {
|
|||
uint8_t plr_lifes;
|
||||
uint8_t plr_bombs;
|
||||
uint8_t plr_moveflags;
|
||||
|
||||
|
||||
// events
|
||||
ReplayEvent *events;
|
||||
uint16_t ecount;
|
||||
|
||||
|
||||
// The fields below should not be stored
|
||||
int capacity;
|
||||
int playpos;
|
||||
|
|
Loading…
Reference in a new issue