]> granicus.if.org Git - nethack/commitdiff
fix issue #509 - shop 'glob' pricing segfault
authorPatR <rankin@nethack.org>
Wed, 12 May 2021 23:13:40 +0000 (16:13 -0700)
committerPatR <rankin@nethack.org>
Wed, 12 May 2021 23:13:40 +0000 (16:13 -0700)
A recent change made it possible for a glob to have its dknown flag
cleared and that exposed globby_bill_fixup() passing Null shopkeeper
to get_cost(), triggering a crash.

Make the routine that clears dknown/known/bknown/&c also be the
routine used to initialize those flags for a new object so that it
is the place that handles various special cases.  That hides the
shop bug again.

But also fix the shop bug even though it won't be triggered.

Fixes #509

doc/fixes37.0
include/extern.h
src/invent.c
src/mkobj.c
src/shk.c

index 13a5329b435d349a577e85d4aa3cdafc53c41ae0..6f375922621aeb7b4eb2ceff1197601b4f53e4e8 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.530 $ $NHDT-Date: 1620590081 2021/05/09 19:54:41 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.532 $ $NHDT-Date: 1620861202 2021/05/12 23:13:22 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -665,6 +665,10 @@ if a <foo> corpse was set to revive as a <foo> zombie and corpse was partly
        calculate zombie's hit points (depended upon how much had been eaten)
 undead turning magic revived corpses flagged as no-revive if they were being
        carried but not if they were zapped while on the floor
+forgetting an item's known/dknown/bknown/&c settings when picked up by unseen
+       monster made it possible to trigger a latent shop bug with globs;
+       avoid clearing dknown flag for globs
+fix globby_bill_fixup to use shopkeeper instead of Null for glob pricing
 
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
index 0fb77b302bf38e73a32f034fe89d68cbea23c7ca..0e87812ad5d5b43be1a4b6f92fef22e321413245 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 extern.h        $NHDT-Date: 1620348705 2021/05/07 00:51:45 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.969 $ */
+/* NetHack 3.7 extern.h        $NHDT-Date: 1620861202 2021/05/12 23:13:22 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.970 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1014,7 +1014,6 @@ extern int ggetobj(const char *, int(*)(struct obj *), int, boolean,
                    unsigned *);
 extern int askchain(struct obj **, const char *, int, int(*)(struct obj *),
                     int(*)(struct obj *), int, const char *);
-extern void unknow_object(struct obj *);
 extern void set_cknown_lknown(struct obj *);
 extern void fully_identify_obj(struct obj *);
 extern int identify(struct obj *);
@@ -1308,6 +1307,7 @@ extern void replace_object(struct obj *, struct obj *);
 extern struct obj *unknwn_contnr_contents(struct obj *);
 extern void bill_dummy_object(struct obj *);
 extern void costly_alteration(struct obj *, int);
+extern void unknow_object(struct obj *);
 extern struct obj *mksobj(int, boolean, boolean);
 extern int bcsign(struct obj *);
 extern int weight(struct obj *);
index 5b9358dad4391a17e1fbe4c5a03c9267cadce4e8..53567c069ccbe99a4ea8b9175059add78a7f0cde 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 invent.c        $NHDT-Date: 1620329776 2021/05/06 19:36:16 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ */
+/* NetHack 3.7 invent.c        $NHDT-Date: 1620861205 2021/05/12 23:13:25 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.331 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2150,19 +2150,6 @@ askchain(struct obj **objchn, /* *objchn might change */
     return cnt;
 }
 
-/* hero is losing access to previously known info about an object
-   (called when an unseen monster picks up or uses the object) */
-void
-unknow_object(struct obj *obj)
-{
-    obj->dknown = 0;
-    obj->bknown = obj->rknown = 0;
-    obj->cknown = obj->lknown = 0;
-    /* awareness of charges or enchantment has gone poof... */
-    if (objects[obj->otyp].oc_uses_known)
-        obj->known = 0;
-}
-
 /*
  *      Object identification routines:
  */
index 8fef52db36ad1fed5a801143f0ccb0df280002c6..fe1565380ebc84c9702200e2cd7860fc644b7f28 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 mkobj.c $NHDT-Date: 1619919403 2021/05/02 01:36:43 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.198 $ */
+/* NetHack 3.7 mkobj.c $NHDT-Date: 1620861208 2021/05/12 23:13:28 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.199 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -708,6 +708,30 @@ static const char dknowns[] = { WAND_CLASS,   RING_CLASS, POTION_CLASS,
                                 SCROLL_CLASS, GEM_CLASS,  SPBOOK_CLASS,
                                 WEAPON_CLASS, TOOL_CLASS, 0 };
 
+/* some init for a brand new object, or partial re-init when hero loses
+   potentially known info about an object (called when an unseen monster
+   picks up or uses it); moved from invent.c to here for access to dknowns */
+void
+unknow_object(struct obj *obj)
+{
+    obj->dknown = index(dknowns, obj->oclass) ? 0 : 1;
+    if ((obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD)
+        || obj->otyp == SHIELD_OF_REFLECTION
+        || objects[obj->otyp].oc_merge)
+        obj->dknown = 0;
+    /* globs always have dknown flag set (to maximize merging) but for new
+       object, globby flag won't be set yet so isn't available to check */
+    if (Is_pudding(obj))
+        obj->dknown = 1;
+
+    obj->bknown = obj->rknown = 0;
+    obj->cknown = obj->lknown = 0;
+    /* for an existing object, awareness of charges or enchantment has
+       gone poof...  [object types which don't use the known flag have
+       it set True for some reason] */
+    obj->known = objects[obj->otyp].oc_uses_known ? 0 : 1;
+}
+
 /* mksobj(): create a specific type of object; result it always non-Null */
 struct obj *
 mksobj(int otyp, boolean init, boolean artif)
@@ -726,15 +750,7 @@ mksobj(int otyp, boolean init, boolean artif)
     otmp->oclass = let;
     otmp->otyp = otyp;
     otmp->where = OBJ_FREE;
-    otmp->dknown = index(dknowns, let) ? 0 : 1;
-    if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD)
-        || otmp->otyp == SHIELD_OF_REFLECTION
-        || objects[otmp->otyp].oc_merge)
-        otmp->dknown = 0;
-    if (!objects[otmp->otyp].oc_uses_known)
-        otmp->known = 1;
-    otmp->lknown = 0;
-    otmp->cknown = 0;
+    unknow_object(otmp); /* set up dknown and known: non-0 for some things */
     otmp->corpsenm = NON_PM;
     otmp->lua_ref_cnt = 0;
 
index 0e7efbd58d782d3d065e233c2cda95deb7d38235..9fe5399e361c91a5f83d12a4c1f2ab21a6f3b378 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -1,4 +1,4 @@
-/* NetHack 3.7 shk.c   $NHDT-Date: 1610667899 2021/01/14 23:44:59 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.195 $ */
+/* NetHack 3.7 shk.c   $NHDT-Date: 1620861209 2021/05/12 23:13:29 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.197 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -4740,7 +4740,7 @@ globby_bill_fixup(struct obj* obj_absorber, struct obj* obj_absorbed)
     struct bill_x *bp, *bp_absorber = (struct bill_x *) 0;
     struct monst *shkp = 0;
     struct eshk *eshkp;
-    long amount, per_unit_cost = set_cost(obj_absorbed, shkp);
+    long amount, per_unit_cost;
     boolean floor_absorber = (obj_absorber->where == OBJ_FLOOR);
 
     if (!obj_absorber->globby)
@@ -4769,6 +4769,7 @@ globby_bill_fixup(struct obj* obj_absorber, struct obj* obj_absorbed)
     bp_absorber = onbill(obj_absorber, shkp, FALSE);
     bp = onbill(obj_absorbed, shkp, FALSE);
     eshkp = ESHK(shkp);
+    per_unit_cost = set_cost(obj_absorbed, shkp);
 
     /**************************************************************
      * Scenario 1. Shop-owned glob absorbing into shop-owned glob