]> granicus.if.org Git - nethack/commitdiff
fix #H9164 - crash during restore when swallowed
authorPatR <rankin@nethack.org>
Sat, 31 Aug 2019 01:11:43 +0000 (18:11 -0700)
committerPatR <rankin@nethack.org>
Sat, 31 Aug 2019 01:11:43 +0000 (18:11 -0700)
Subject was "display crash while in curses mode".  Restoring with
perm_invent set in config file or NETHACKOPTIONS when the save was
made while swallowed (regardless of perm_invent at that time) resulted
in a crash when invalid u.ustuck was referenced before restoration had
done its pointer fixups.

init_nhwindows() is called with perm_invent On;
restgamestate() temporarily turns it Off (3.6.2 restore hack);
if/when update_inventory() gets called, curses notices that the
persistent window has been disabled so it tears down all its windows
in order to redraw the screen without that one;
docrt() sees non-Null u.ustuck and calls swallowed();
swallowed() tries to use the value of that pointer rather than just
Null/non-Null but the value is from the previous game session, not
valid for the current session;
crash.

Make yet another attempt to prevent update_inventory() from being
called during restore.  curses won't try to redraw and the crash
won't happen.  But the invalid pointer is still lurking (until an
eventual fixup later during restore).

An earlier fix for update_inventory() during restore actually handled
this problem (for the most common trigger, setworn(), but not in
general), so the 3.6.2 behavior is a regression.

doc/fixes36.3
include/extern.h
include/winprocs.h
src/display.c
src/invent.c

index 5f8b0815a43cc51f332b3724b63b2cf4e8837e18..8677345fb1f1eeb67b3cb445893c9475efe26333 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.103 $ $NHDT-Date: 1565833748 2019/08/15 01:49:08 $
+$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.104 $ $NHDT-Date: 1567213888 2019/08/31 01:11:28 $
 
 This fixes36.3 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -125,6 +125,8 @@ when a shape-shifted sandestin was turned to stone, it died and reverted to
        sandestins are immune to stoning; net result was monster dying twice,
        triggering "dmonsfree: N removed doesn't match N+1 pending" warning;
        instead of dying, make it revert to sandestin form with full health
+toggling perm_invent (where supported) while swallowed or underwater didn't
+       necessarily update the persistent inventory window right away
 
 
 Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
@@ -214,6 +216,9 @@ curses+'perm_invent': if too many entries for window height, last one which
 curses+'perm_invent': top line was wasted (left blank) when borders Off
 curses+'perm_invent': don't highlight inventory letters since nothing is
        selectable from the menu comprising the persistent inventory window
+curses+'perm_invent': could crash during restore if game was saved while
+       hero was swallowed (invalid u.ustuck pointer; suppressing attempts to
+       update persistent inventory window during restore hides the problem)
 curses+'popup_dialog': show the text cursor at the end of prompts for single
        character input
 curses+DUMPLOG: pass along old messages from save file and quest message
index 90548cf37bf58f2dc62c5c269a6d685b79db25a0..7c37297b35f8fb6a8b364df26b1f385657f88b7b 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1562114349 2019/07/03 00:39:09 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.715 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1567213888 2019/08/31 01:11:28 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.728 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1013,6 +1013,7 @@ E int FDECL(identify, (struct obj *));
 E int FDECL(count_unidentified, (struct obj *));
 E void FDECL(identify_pack, (int, BOOLEAN_P));
 E void NDECL(learn_unseen_invent);
+E void NDECL(update_inventory);
 E void FDECL(prinv, (const char *, struct obj *, long));
 E char *FDECL(xprname,
               (struct obj *, const char *, CHAR_P, BOOLEAN_P, long, long));
index 36962750eec27c0e7eb7cfde6006752d449772d6..cc3b4046c544bc0ddd3dc4cf47904a47ed2ee439 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 winprocs.h      $NHDT-Date: 1553204011 2019/03/21 21:33:31 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.47 $ */
+/* NetHack 3.6 winprocs.h      $NHDT-Date: 1567213890 2019/08/31 01:11:30 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.50 $ */
 /* Copyright (c) David Cohrs, 1992                               */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -112,7 +112,7 @@ extern
 #define end_menu (*windowprocs.win_end_menu)
 #define select_menu (*windowprocs.win_select_menu)
 #define message_menu (*windowprocs.win_message_menu)
-#define update_inventory (*windowprocs.win_update_inventory)
+
 #define mark_synch (*windowprocs.win_mark_synch)
 #define wait_synch (*windowprocs.win_wait_synch)
 #ifdef CLIPPING
index 70a008a0af59f08b733c6a328f632bd1c7f1ae59..7d948deaea258e272fb895e32b8fe42166801af5 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 display.c       $NHDT-Date: 1560085863 2019/06/09 13:11:03 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.104 $ */
+/* NetHack 3.6 display.c       $NHDT-Date: 1567213890 2019/08/31 01:11:30 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.106 $ */
 /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
 /* and Dave Cohrs, 1990.                                          */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1368,15 +1368,15 @@ docrt()
 
     if (u.uswallow) {
         swallowed(1);
-        return;
+        goto post_map;
     }
     if (Underwater && !Is_waterlevel(&u.uz)) {
         under_water(1);
-        return;
+        goto post_map;
     }
     if (u.uburied) {
         under_ground(1);
-        return;
+        goto post_map;
     }
 
     /* shut down vision */
@@ -1403,6 +1403,8 @@ docrt()
     /* overlay with monsters */
     see_monsters();
 
+ post_map:
+
     /* perm_invent */
     update_inventory();
 
index fe21fa7b49d8886aebd78636e8c8bc66ecac46da..1f8bae8c43670a33284c8da4d0a53fc9124f45cb 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 invent.c        $NHDT-Date: 1562203850 2019/07/04 01:30:50 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.261 $ */
+/* NetHack 3.6 invent.c        $NHDT-Date: 1567213892 2019/08/31 01:11:32 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.262 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2398,6 +2398,26 @@ learn_unseen_invent()
     update_inventory();
 }
 
+/* persistent inventory window is maintained by interface code;
+   'update_inventory' used to be a macro for
+   (*windowprocs.win_update_inventory) but the restore hackery
+   was getting out of hand; this is now a central call point */
+void
+update_inventory()
+{
+    if (restoring)
+        return;
+
+    /*
+     * Ought to check (windowprocs.wincap2 & WC2_PERM_INVENT) here....
+     *
+     * We currently don't skip this call when iflags.perm_invent is False
+     * because curses uses that to disable a previous perm_invent window
+     * (after toggle via 'O'; perhaps the options code should handle that).
+     */
+    (*windowprocs.win_update_inventory)();
+}
+
 /* should of course only be called for things in invent */
 STATIC_OVL char
 obj_to_let(obj)