]> granicus.if.org Git - nethack/commitdiff
strange object vs generic objects
authorPatR <rankin@nethack.org>
Sun, 15 Jan 2023 09:45:14 +0000 (01:45 -0800)
committerPatR <rankin@nethack.org>
Sun, 15 Jan 2023 09:45:14 +0000 (01:45 -0800)
Try to fix a fuzzer issue.  I wasn't able to reproduce it so am not
sure whether this actually fixes it.  A mimic seemed to be mimicking
object #1 (generic ILLOBJ_CLASS object which shouldn't occur) rather
than #0 (strange object).  Strange object always has dknown==1 and
generic objects should always have dknown==0 but farlook of mystery
object #1 had its dknown flag set.

An earlier fix to force non-Null oc_name when formatting objects in
order to pacify the static analyzer might have been the reason that
the problem couldn't be reproduced.

This includes a few miscellaneous changes made while unsuccessfully
hunting for the problem.

include/display.h
include/extern.h
src/mkobj.c
src/o_init.c
src/pager.c

index 5cf72c225ab1fceb4a3d268c73962572dcc93937..a09ddf027a238fbac70cad03e5960e15b47fb0bd 100644 (file)
@@ -850,25 +850,24 @@ enum glyph_offsets {
      || glyph_is_male_statue_piletop(glyph))
 #define glyph_is_statue(glyph) \
     (glyph_is_male_statue(glyph) || glyph_is_fem_statue(glyph))
-/* note: 'strange object' gets [mis?]classified as generic here but that
-   shouldn't impact anything; to do it properly, glyph_is_normal_generic_obj()
-   and glyph_is_piletop_generic_obj() should use '>' rather than '>=', and
-   glyph_is_normal_object() and glyph_is_normal_piletop_obj() should include
-   (glyph == {GLYPH_OBJ_OFF,GLYPH_OBJ_PILETOP_OFF}) to test for object #0 */
+/* generic objects are after strange object (GLYPH_OBJ_OFF) and before
+   other objects (GLYPH_OBJ_OFF + MAXOCLASSES) */
 #define glyph_is_normal_generic_obj(glyph) \
-    ((glyph) >= GLYPH_OBJ_OFF && (glyph) < GLYPH_OBJ_OFF + MAXOCLASSES)
+    ((glyph) > GLYPH_OBJ_OFF && (glyph) < GLYPH_OBJ_OFF + MAXOCLASSES)
 #define glyph_is_piletop_generic_obj(glyph) \
-    ((glyph) >= GLYPH_OBJ_PILETOP_OFF                           \
+    ((glyph) > GLYPH_OBJ_PILETOP_OFF                            \
      && (glyph) < GLYPH_OBJ_PILETOP_OFF + MAXOCLASSES)
 #define glyph_is_generic_object(glyph) \
     (glyph_is_normal_generic_obj(glyph)                         \
      || glyph_is_piletop_generic_obj(glyph))
 #define glyph_is_normal_piletop_obj(glyph) \
-    (((glyph) >= GLYPH_OBJ_PILETOP_OFF + MAXOCLASSES)           \
-     && ((glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS)))
+    ((glyph) == GLYPH_OBJ_PILETOP_OFF                           \
+     || ((glyph) > GLYPH_OBJ_PILETOP_OFF + MAXOCLASSES          \
+         && (glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS)))
 #define glyph_is_normal_object(glyph) \
-    ((((glyph) >= GLYPH_OBJ_OFF + MAXOCLASSES)                  \
-      && ((glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS)))             \
+    ((glyph) == GLYPH_OBJ_OFF                                   \
+     || ((glyph) >= GLYPH_OBJ_OFF + MAXOCLASSES                 \
+         && (glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS))            \
      || glyph_is_normal_piletop_obj(glyph))
 
 #if 0   /* [note: out of date] */
index bc3f0e97a534ef62d3b2413b42488d794f08db82..c1ba30964c50b9b5c3caa9958de1e1266189e91c 100644 (file)
@@ -1443,7 +1443,7 @@ extern void free_omailcmd(struct obj *);
 extern struct obj *mkobj_at(char, coordxy, coordxy, boolean);
 extern struct obj *mksobj_at(int, coordxy, coordxy, boolean, boolean);
 extern struct obj *mksobj_migr_to_species(int, unsigned, boolean, boolean);
-extern struct obj *mkobj(int, boolean);
+extern struct obj *mkobj(int, boolean) NONNULL;
 extern int rndmonnum_adj(int, int);
 extern int rndmonnum(void);
 extern boolean bogon_is_pname(char);
@@ -1457,7 +1457,7 @@ extern void bill_dummy_object(struct obj *);
 extern void costly_alteration(struct obj *, int);
 extern void clear_dknown(struct obj *);
 extern void unknow_object(struct obj *);
-extern struct obj *mksobj(int, boolean, boolean);
+extern struct obj *mksobj(int, boolean, boolean) NONNULL;
 extern int bcsign(struct obj *);
 extern int weight(struct obj *);
 extern struct obj *mkgold(long, coordxy, coordxy);
index 79013ce7fecd2b294bf1e02f5cab9431833c7891..9eb3dac93c131d521991188535846a1c30192a24 100644 (file)
@@ -789,7 +789,7 @@ unknow_object(struct obj *obj)
     obj->known = objects[obj->otyp].oc_uses_known ? 0 : 1;
 }
 
-/* mksobj(): create a specific type of object; result it always non-Null */
+/* mksobj(): create a specific type of object; result is always non-Null */
 struct obj *
 mksobj(int otyp, boolean init, boolean artif)
 {
index d9902248fa7ebaa8e553e4240b08be3943aa23c0..80d4f8f59a4a47583768aa22498e1e24e9d6814c 100644 (file)
@@ -182,7 +182,9 @@ init_objects(void)
         prevoclass = (int) oclass;
     }
     /* extra entry allows deriving the range of a class via
-       bases[class] through bases[class+1]-1 for all classes */
+       bases[class] through bases[class+1]-1 for all classes
+       (except for ILLOBJ_CLASS which is separated from WEAPON_CLASS
+       by generic objects) */
     gb.bases[MAXOCLASSES] = NUM_OBJECTS;
     /* hypothetically someone might remove all objects of some class,
        or be adding a new class and not populated it yet, leaving gaps
@@ -228,13 +230,16 @@ init_oclass_probs(void)
     int oclass;
     for (oclass = 0; oclass < MAXOCLASSES; ++oclass) {
         sum = 0;
+        /* note: for ILLOBJ_CLASS, bases[oclass+1]-1 isn't the last item
+           in the class; but all the generic items have probability 0 so
+           adding them to 'sum' has no impact */
         for (i = gb.bases[oclass]; i < gb.bases[oclass + 1]; ++i) {
             sum += objects[i].oc_prob;
         }
         if (sum <= 0 && oclass != ILLOBJ_CLASS
             && gb.bases[oclass] != gb.bases[oclass + 1]) {
-            impossible("zero or negative probability total for oclass %d",
-                       oclass);
+            impossible("%s (%d) probability total for oclass %d",
+                       !sum ? "zero" : "negative", sum, oclass);
             /* gracefully fail by setting all members of this class to 1 */
             for (i = gb.bases[oclass]; i < gb.bases[oclass + 1]; ++i) {
                 objects[i].oc_prob = 1;
index 59e7489cf458e9d302f651c58a42c0b342c122a5..adb6d93ca736420d194ac4245376eaaf2f8e0b7d 100644 (file)
@@ -296,8 +296,10 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p)
 }
 
 static void
-look_at_object(char *buf, /* output buffer */
-               coordxy x, coordxy y, int glyph)
+look_at_object(
+    char *buf, /* output buffer */
+    coordxy x, coordxy y,
+    int glyph)
 {
     struct obj *otmp = 0;
     boolean fakeobj = object_from_map(glyph, x, y, &otmp);