From 756f6a10062214afc6e3f8ab4b40eae06b41137c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 29 Nov 2019 18:31:45 -0800 Subject: [PATCH] fix a memory leak Memory allocated for a trap in getlev() wasn't being freed. There is already one extra allocation which is supposed to get freed after the loop, but the 'keepgoing' flag caused an extra trap allocation before loop termination. So the unintentional one got freed but did so by intercepting the free for the end-of-list one. Fruit had similar code which applied to full game save and restore rather than level save and restore so wasn't as noticeable. --- src/restore.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/restore.c b/src/restore.c index c4c725b2c..6aae06343 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 restore.c $NHDT-Date: 1561485720 2019/06/25 18:02:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.131 $ */ +/* NetHack 3.6 restore.c $NHDT-Date: 1575081102 2019/11/30 02:31:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -565,12 +565,11 @@ static struct fruit * loadfruitchn(nhfp) NHFILE *nhfp; { - register struct fruit *flist, *fnext = (struct fruit *) 0; - boolean keepgoing; + register struct fruit *flist, *fnext; flist = 0; - keepgoing = TRUE; - while (fnext = newfruit(), keepgoing) { + for (;;) { + fnext = newfruit(); if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t)fnext, sizeof *fnext); if (nhfp->fieldlevel) @@ -579,7 +578,7 @@ NHFILE *nhfp; fnext->nextf = flist; flist = fnext; } else - keepgoing = FALSE; + break; } dealloc_fruit(fnext); return flist; @@ -1227,7 +1226,6 @@ boolean ghostly; int hpid; xchar dlvl; int x, y; - boolean keepgoing; #ifdef TOS short tlev; #endif @@ -1288,7 +1286,8 @@ boolean ghostly; for (c = 0; c < COLNO; ++c) for (r = 0; r < ROWNO; ++r) - sfi_schar(nhfp, &g.lastseentyp[c][r], "lev", "g.lastseentyp", 1); + sfi_schar(nhfp, &g.lastseentyp[c][r], + "lev", "g.lastseentyp", 1); sfi_long(nhfp, &g.omoves, "lev", "timestmp", 1); } @@ -1331,9 +1330,10 @@ boolean ghostly; /* rest_worm(fd); */ /* restore worm information */ rest_worm(nhfp); /* restore worm information */ + g.ftrap = 0; - keepgoing = TRUE; - while (trap = newtrap(), keepgoing) { + for (;;) { + trap = newtrap(); if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t)trap, sizeof(struct trap)); if (nhfp->fieldlevel) @@ -1342,9 +1342,10 @@ boolean ghostly; trap->ntrap = g.ftrap; g.ftrap = trap; } else - keepgoing = FALSE; + break; } dealloc_trap(trap); + fobj = restobjchn(nhfp, ghostly, FALSE); find_lev_obj(); /* restobjchn()'s `frozen' argument probably ought to be a callback