From e375c8bd05d95bf6f80a775f6d546d5e03c2a513 Mon Sep 17 00:00:00 2001 From: "John \"Elwin\" Edwards" Date: Thu, 8 Aug 2013 12:41:35 -0700 Subject: [PATCH] Properly handle invalid room references in savefiles. In all games, rs_write_room_reference() stored -1 for a nonexistent room, but rs_read_room_reference() did not check for out-of-bounds values, leading to pointers to rooms[-1], which sometimes caused crashes. rs_read_room_reference() has now been modified to use NULL instead. Some of the games required further changes to replace NULL with the pointer to the actual room. Others are capable of handling NULL for objects not in any room. --- arogue5/state.c | 5 ++++- rogue3/state.c | 8 ++++++-- rogue4/state.c | 13 ++++++++++++- rogue5/state.c | 16 ++++++++++++++-- srogue/state.c | 5 ++++- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/arogue5/state.c b/arogue5/state.c index 9f18bab..f5fdb43 100644 --- a/arogue5/state.c +++ b/arogue5/state.c @@ -1661,7 +1661,10 @@ rs_read_room_reference(int inf, struct room **rp) rs_read_int(inf, &i); - *rp = &rooms[i]; + if (i >= 0 && i < MAXROOMS) + *rp = &rooms[i]; + else + *rp = NULL; return(READSTAT); } diff --git a/rogue3/state.c b/rogue3/state.c index 0bc6ba2..9d1855c 100644 --- a/rogue3/state.c +++ b/rogue3/state.c @@ -765,8 +765,12 @@ rs_read_room_reference(FILE *savef, struct room **rp) rs_read_int(savef, &i); - if (!encerror()) - *rp = &rooms[i]; + if (!encerror()) { + if (i >= 0 && i < MAXROOMS) + *rp = &rooms[i]; + else + *rp = NULL; + } } void diff --git a/rogue4/state.c b/rogue4/state.c index d2035df..294e613 100644 --- a/rogue4/state.c +++ b/rogue4/state.c @@ -1212,7 +1212,10 @@ rs_read_room_reference(int inf, struct room **rp) rs_read_int(inf, &i); - *rp = &rooms[i]; + if (i >= 0 && i < MAXROOMS) + *rp = &rooms[i]; + else + *rp = NULL; return(READSTAT); } @@ -2060,6 +2063,7 @@ int rs_restore_file(int inf) { bool junk; + THING *mitem; int endian = 0x01020304; big_endian = ( *((char *)&endian) == 0x01 ); @@ -2156,6 +2160,13 @@ rs_restore_file(int inf) rs_read(inf, wand_mons, sizeof(wand_mons)); /* 5.2-monsters.c */ rs_read_coord(inf, &nh); /* 5.2-move.c */ rs_read_boolean(inf, &got_genocide); /* 5.2-things.c */ + + if (proom == NULL) + proom = roomin(&hero); + for (mitem = mlist; mitem != NULL; mitem = mitem->l_next) { + if (mitem->t_room == NULL) + mitem->t_room = roomin(&(mitem->t_pos)); + } return(READSTAT); } diff --git a/rogue5/state.c b/rogue5/state.c index 870c76c..5132386 100644 --- a/rogue5/state.c +++ b/rogue5/state.c @@ -804,8 +804,12 @@ rs_read_room_reference(FILE *savef, struct room **rp) rs_read_int(savef, &i); - if (!encerror()) - *rp = &rooms[i]; + if (!encerror()) { + if (i >= 0 && i < MAXROOMS) + *rp = &rooms[i]; + else + *rp = NULL; + } } void @@ -1384,6 +1388,7 @@ rs_save_file(FILE *savef) int rs_restore_file(FILE *savef) { + THING *mitem; encclearerr(); rs_read_int(savef, &noscore); @@ -1446,5 +1451,12 @@ rs_restore_file(FILE *savef) rs_read_int(savef,&group); rs_read_window(savef,stdscr); + if (player.t_room == NULL) + player.t_room = roomin(&hero); + for (mitem = mlist; mitem != NULL; mitem = mitem->l_next) { + if (mitem->t_room == NULL) + mitem->t_room = roomin(&(mitem->t_pos)); + } + return( encclearerr() ); } diff --git a/srogue/state.c b/srogue/state.c index 0d01d78..d9bf35c 100644 --- a/srogue/state.c +++ b/srogue/state.c @@ -1128,7 +1128,10 @@ rs_read_room_reference(int inf, struct room **rp) rs_read_int(inf, &i); - *rp = &rooms[i]; + if (i >= 0 && i < MAXROOMS) + *rp = &rooms[i]; + else + *rp = NULL; return(READSTAT); }