From b4197a226397ae8c7e9d214a349568073e45eed8 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 24 Jul 2023 23:40:30 +0100 Subject: [PATCH] Double-free emergency fix for virtual resources - vres_GetMap guarantees the same memory for the same lump id, provided it's active - vres_Free won't delete curmapvirt unless you do some silly temp pointer stuff --- src/p_setup.c | 11 +++++++++-- src/p_setup.h | 1 + src/w_wad.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6ee45f218..ea2fb595d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8280,8 +8280,15 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) } // Now safe to free. - vres_Free(curmapvirt); - curmapvirt = NULL; + // We do the following silly + // construction because vres_Free + // no-sells deletions of pointers + // that are == curmapvirt. + { + virtres_t *temp = curmapvirt; + curmapvirt = NULL; + vres_Free(temp); + } if (!reloadinggamestate) { diff --git a/src/p_setup.h b/src/p_setup.h index fd343f927..e626363f4 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -35,6 +35,7 @@ extern boolean levelloading; extern UINT8 levelfadecol; extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame +extern virtres_t *curmapvirt; /* for levelflat type */ enum diff --git a/src/w_wad.c b/src/w_wad.c index a2f249f3f..96fe606be 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -2354,6 +2354,12 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum) virtlump_t* vlumps = NULL; size_t numlumps = 0; + if (lastloadedmaplumpnum == lumpnum && curmapvirt != NULL) + { + // Avoid duplicating all our hard work. + return curmapvirt; + } + if (W_IsLumpWad(lumpnum)) { UINT32 realentry; @@ -2430,6 +2436,12 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum) */ void vres_Free(virtres_t* vres) { + if (vres == curmapvirt) + { + // No-sell multiple references. + return; + } + while (vres->numlumps--) { if (vres->vlumps[vres->numlumps].data)