]> granicus.if.org Git - nethack/commitdiff
create_particular long worm tail vs mkclass
authorPatR <rankin@nethack.org>
Wed, 2 Jan 2019 21:42:45 +0000 (13:42 -0800)
committerPatR <rankin@nethack.org>
Wed, 2 Jan 2019 21:42:45 +0000 (13:42 -0800)
Similar to ^G of 'I' triggering impossible "mkclass found no class 35
monsters", using a leading substring of "long worm tail" (other than
"l" and "long worm") would trigger impossible "mkclass found no class
59 monsters and kill the fuzzer when it escalates impossible to panic.
Tighten up the substring matching.

^G of '~' wasn't affected; it deliberately creates a long worm rather
than the tail of one.  But it was possible to ask for "long worm tail"
as a specific monster type and then override the switch to long worm
when prompted about whether to force the originally specified critter.
I've added a check to prevent that opportunity to override even though
a tail without a head seemed to be harmless.

doc/fixes36.2
src/mondata.c
src/read.c

index fe8568a2ddccca6b81ae35c1b399fa5bf26370b3..320d6288e25bc251c8335b43134f9d79725bf3f3 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.219 $ $NHDT-Date: 1546212616 2018/12/30 23:30:16 $
+$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.220 $ $NHDT-Date: 1546465283 2019/01/02 21:41:23 $
 
 This fixes36.2 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -360,10 +360,12 @@ when built with STATUS_HILITES enabled (the default), gold on status line
        was missing '$' prefix for symset:Blank
 wizard mode ^G, creating a monster of class 'I' yielded impossible "mkclass
        found no class 35 monsters"
-in some unknown circumstance, examining something on the map could match bogus
-       monster class #0 and trigger impossible "Alphabet soup: 'an("")'."
-       (fix avoids the warning but underlying cause is a mystery; noticed
-       with the fuzzer, which swaps symbol sets in and out at random)
+wizard mode ^G, creating a monster via class name using "lo" through "long wor"
+       or "long worm t" through "long worm tail" yielded impossible "mkclass
+       found no class 59 monsters" (class '~' creates a long worm as intended)
+if bouldersym bug (via 'O', above) put a <NUL> ('\0') on the map, examining
+       that spot matched placeholder monster class #0 and triggered impossible
+       "Alphabet soup: 'an("")'."
 tty: turn off an optimization that is the suspected cause of Windows reported
        partial status lines following level changes
 tty: ensure that current status fields are always copied to prior status
index 62dea9a10f3d6473c5928de1a75c176e4dc11e51..9feeeae4e83c12f2f90c079c27ec910d0079069c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mondata.c       $NHDT-Date: 1543545188 2018/11/30 02:33:08 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.69 $ */
+/* NetHack 3.6 mondata.c       $NHDT-Date: 1546465283 2019/01/02 21:41:23 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.70 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -781,11 +781,12 @@ const char *in_str;
     }
 
     for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
-        register int m_i_len = strlen(mons[i].mname);
+        register int m_i_len = (int) strlen(mons[i].mname);
 
         if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
             if (m_i_len == slen) {
-                return i; /* exact match */
+                mntmp = i;
+                break; /* exact match */
             } else if (slen > m_i_len
                        && (str[m_i_len] == ' '
                            || !strcmpi(&str[m_i_len], "s")
@@ -841,7 +842,7 @@ int *mndx_p;
         { 0, NON_PM }
     };
     const char *p, *x;
-    int i;
+    int i, len;
 
     if (mndx_p)
         *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
@@ -863,6 +864,8 @@ int *mndx_p;
         return i;
     } else {
         /* multiple characters */
+        if (!strcmpi(in_str, "long")) /* not enough to match "long worm" */
+            return 0; /* avoid false whole-word match with "long worm tail" */
         in_str = makesingular(in_str);
         /* check for special cases */
         for (i = 0; falsematch[i]; i++)
@@ -878,9 +881,12 @@ int *mndx_p;
                 return mons[i].mlet;
             }
         /* check monster class descriptions */
+        len = (int) strlen(in_str);
         for (i = 1; i < MAXMCLASSES; i++) {
             x = def_monsyms[i].explain;
-            if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
+            if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' ')
+                && ((int) strlen(p) >= len
+                    && (p[len] == '\0' || p[len] == ' ')))
                 return i;
         }
         /* check individual species names */
index a52a0317bff76a469d94bc2f1eb509df06f27b70..562b52bf15de86a195430c915d11f302d684fb75 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 read.c  $NHDT-Date: 1546053040 2018/12/29 03:10:40 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.163 $ */
+/* NetHack 3.6 read.c  $NHDT-Date: 1546465285 2019/01/02 21:41:25 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2498,6 +2498,10 @@ struct _create_particular_data *d;
         d->which = PM_STALKER;
         d->monclass = MAXMCLASSES;
         return TRUE;
+    } else if (d->monclass == S_WORM_TAIL) { /* empty monster class */
+        d->which = PM_LONG_WORM;
+        d->monclass = MAXMCLASSES;
+        return TRUE;
     } else if (d->monclass > 0) {
         d->which = urole.malenum; /* reset from NON_PM */
         return TRUE;
@@ -2516,7 +2520,8 @@ struct _create_particular_data *d;
 
     if (!d->randmonst) {
         firstchoice = d->which;
-        if (cant_revive(&d->which, FALSE, (struct obj *) 0)) {
+        if (cant_revive(&d->which, FALSE, (struct obj *) 0)
+            && firstchoice != PM_LONG_WORM_TAIL) {
             /* wizard mode can override handling of special monsters */
             char buf[BUFSZ];