fixed crash bug caused by freeing string buffer twice
authorHolger Schemel <info@artsoft.org>
Thu, 18 Feb 2021 23:24:23 +0000 (00:24 +0100)
committerHolger Schemel <info@artsoft.org>
Thu, 18 Feb 2021 23:24:23 +0000 (00:24 +0100)
When loading a snapshot, a string pointer in the tape structure was
also restored from the snapshot, overwriting a potentially already
changed string pointer, therefore causing the next free() to crash.

src/files.c
src/tape.c
src/tape.h

index 39c0321ac51ad81576d56661450db81803a48ed9..5cca0e3055b97595d87e418087e9dac35b3be83a 100644 (file)
@@ -7765,16 +7765,21 @@ static int LoadTape_SCRN(File *file, int chunk_size, struct TapeInfo *tape)
 
 static int LoadTape_INFO(File *file, int chunk_size, struct TapeInfo *tape)
 {
+  char *level_identifier = NULL;
   int level_identifier_size;
   int i;
 
   level_identifier_size = getFile16BitBE(file);
 
-  tape->level_identifier =
-    checked_realloc(tape->level_identifier, level_identifier_size);
+  level_identifier = checked_malloc(level_identifier_size);
 
   for (i = 0; i < level_identifier_size; i++)
-    tape->level_identifier[i] = getFile8Bit(file);
+    level_identifier[i] = getFile8Bit(file);
+
+  strncpy(tape->level_identifier, level_identifier, MAX_FILENAME_LEN);
+  tape->level_identifier[MAX_FILENAME_LEN] = '\0';
+
+  checked_free(level_identifier);
 
   tape->level_nr = getFile16BitBE(file);
 
index 2300f00b2d89b9f34015ca76998fbeac4de6e7e9..c1e4bcea9f05cb67f8035a0af5cd0336c014cd6b 100644 (file)
@@ -541,7 +541,11 @@ void TapeErase(void)
   tape.length_seconds = 0;
 
   if (leveldir_current)
-    setString(&tape.level_identifier, leveldir_current->identifier);
+  {
+    strncpy(tape.level_identifier, leveldir_current->identifier,
+           MAX_FILENAME_LEN);
+    tape.level_identifier[MAX_FILENAME_LEN] = '\0';
+  }
 
   tape.level_nr = level_nr;
   tape.pos[tape.counter].delay = 0;
@@ -1160,12 +1164,7 @@ static boolean checkTapesFromSameLevel(struct TapeInfo *t1, struct TapeInfo *t2)
 
 static void CopyTape(struct TapeInfo *tape_from, struct TapeInfo *tape_to)
 {
-  if (tape_to->level_identifier != NULL)
-    checked_free(tape_to->level_identifier);
-
   *tape_to = *tape_from;
-
-  tape_to->level_identifier = getStringCopy(tape_from->level_identifier);
 }
 
 static void SwapTapes(struct TapeInfo *t1, struct TapeInfo *t2)
index 332de217e6058ae9596c86727e1b8acfaa1263be..a829448a5e007c5c959d66dfc32baa1b9e46457c 100644 (file)
@@ -178,7 +178,7 @@ struct TapeInfo
   int game_version;    // game release version the tape was created with
   int engine_version;  // game engine version the tape was recorded with
 
-  char *level_identifier;
+  char level_identifier[MAX_FILENAME_LEN + 1];
   int level_nr;
   unsigned int random_seed;
   unsigned int date;