]> granicus.if.org Git - nethack/commitdiff
timer validations
authorPatR <rankin@nethack.org>
Sat, 27 Jul 2019 23:12:24 +0000 (16:12 -0700)
committerPatR <rankin@nethack.org>
Sat, 27 Jul 2019 23:12:24 +0000 (16:12 -0700)
Add the contributed code that checks for attempting to start a
duplicate timer.  It's based on a comment which must have been there
at least 25 years and doesn't solve any known problems, but it is
conceptually similar to the large amount of sanity checking which has
gone into 3.6.x.

It didn't work as is because it was comparing two unions with '=='.
I don't know offhand whether C++ supports that but C doesn't (through
C11 at least; don't know about C17).  The union ('anything') is simple
enough that two instances can be compared without jumping through hoops.

I've also added another check for timer 'kind' (level, object, monster,
or global).

doc/fixes36.3
include/timeout.h
src/timeout.c

index 909dbd345a6fb78c212b4ce8008479a90ac4a922..a20fc650e8d6690e1fddd8bd488e4dcbad5f0863 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.94 $ $NHDT-Date: 1562838835 2019/07/11 09:53:55 $
+$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.95 $ $NHDT-Date: 1564269131 2019/07/27 23:12:11 $
 
 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,
@@ -105,6 +105,8 @@ when farlook describes a monster at a visible spot as trapped, reveal the trap
 fix theft when poly'd into nymph form; 3.6.2 change made that anger the victim
 hero poly'd into nymph would steal gold along with other items
 change wizard mode #panic to require "yes" if 'paranoid_confirm:quit' is set
+add some additional validation checks when setting up a new timer (triggered
+       by an ancient source comment rather than by any observed problems)
 
 
 Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
index 0cb4c706a7d6471c9138fdd7fe3847088921f2be..0ac85a3c877344500fba0faeeb55f7543f746880 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 timeout.h       $NHDT-Date: 1432512775 2015/05/25 00:12:55 $  $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
+/* NetHack 3.6 timeout.h       $NHDT-Date: 1564269131 2019/07/27 23:12:11 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ */
 /* Copyright 1994, Dean Luick                                    */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -10,10 +10,11 @@ typedef void FDECL((*timeout_proc), (ANY_P *, long));
 
 /* kind of timer */
 enum timer_type {
-    TIMER_LEVEL = 0,   /* event specific to level */
-    TIMER_GLOBAL,  /* event follows current play */
-    TIMER_OBJECT,  /* event follows a object */
-    TIMER_MONSTER /* event follows a monster */
+    TIMER_LEVEL = 0,   /* event specific to level [melting ice] */
+    TIMER_GLOBAL = 1,  /* event follows current play [not used] */
+    TIMER_OBJECT = 2,  /* event follows an object [various] */
+    TIMER_MONSTER = 3, /* event follows a monster [not used] */
+    NUM_TIMER_KINDS    /* 4 */
 };
 
 /* save/restore timer ranges */
index 54a2943c3d0ee3554181718b41a97720d589fb02..3d820b0fb09905d735b0a6737f728dd3b3b14c4c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 timeout.c       $NHDT-Date: 1559664953 2019/06/04 16:15:53 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.90 $ */
+/* NetHack 3.6 timeout.c       $NHDT-Date: 1564269133 2019/07/27 23:12:13 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.91 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2018. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1868,13 +1868,32 @@ short kind;
 short func_index;
 anything *arg;
 {
-    timer_element *gnu;
+    timer_element *gnu, *dup;
 
-    if (func_index < 0 || func_index >= NUM_TIME_FUNCS)
-        panic("start_timer");
+    if (kind < 0 || kind >= NUM_TIMER_KINDS
+        || func_index < 0 || func_index >= NUM_TIME_FUNCS)
+        panic("start_timer (%s: %d)", kind_name(kind), (int) func_index);
 
-    gnu = (timer_element *) alloc(sizeof(timer_element));
-    (void) memset((genericptr_t)gnu, 0, sizeof(timer_element));
+    /* fail if <arg> already has a <func_index> timer running */
+    for (dup = timer_base; dup; dup = dup->next)
+        if (dup->kind == kind
+            && dup->func_index == func_index
+            && dup->arg.a_void == arg->a_void)
+            break;
+    if (dup) {
+        char idbuf[QBUFSZ];
+
+#ifdef VERBOSE_TIMER
+        Sprintf(idbuf, "%s timer", timeout_funcs[func_index].name);
+#else
+        Sprintf(idbuf, "%s timer (%d)", kind_name(kind), (int) func_index);
+#endif
+        impossible("Attempted to start duplicate %s, aborted.", idbuf);
+        return FALSE;
+    }
+
+    gnu = (timer_element *) alloc(sizeof *gnu);
+    (void) memset((genericptr_t) gnu, 0, sizeof *gnu);
     gnu->next = 0;
     gnu->tid = timer_id++;
     gnu->timeout = monstermoves + when;
@@ -1887,7 +1906,6 @@ anything *arg;
     if (kind == TIMER_OBJECT) /* increment object's timed count */
         (arg->a_obj)->timed++;
 
-    /* should check for duplicates and fail if any */
     return TRUE;
 }