]> granicus.if.org Git - nethack/commitdiff
fix out of bounds error in tty_status_update() for BL_HUNGER case
authornhmall <nhmall@nethack.org>
Wed, 26 Sep 2018 21:18:09 +0000 (17:18 -0400)
committernhmall <nhmall@nethack.org>
Wed, 26 Sep 2018 21:18:09 +0000 (17:18 -0400)
The pointer could go out of bounds when decremented if it was pointing
at the start of the status_vals[BL_HUNGER] (empty string).

Also, guard tty_status_update() from an out of range index being
passed to it (botl shouldn't do that, but...).

The legal 1st parameter values for tty_status_update() in 3.6.2 are

BL_RESET     (-2)
BL_FLUSH     (-1)
BL_TITLE     ( 0)
...though to...
BL_CONDITION (22)

  count MAXBLSTATS = (BL_CONDITION + 1)

There's a BL_CHARACTERISTIC (-3) defined in the botl.h header file,
but it is not used in wintty.c and is now screened out along with
everything lower and everything MAXBLSTATS and above.

closes #142
fixes #141

doc/fixes36.2
win/tty/wintty.c

index 0a384683f6def6ebbea1f918095e83e5835ba3c2..67f48721142838208fca81eb21930d655ac5a651 100644 (file)
@@ -167,6 +167,7 @@ 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
        values so that comparisons are correct
+tty: fix an out of bounds error in tty_status_update() for BL_HUNGER case
 X11: its use of genl_status_update exposed a negative index use that could
        lead to a segfault
 
index 7657b1186936bd9d8644238a41f4f4cc8318b27c..34cc45f5db469b96c2bf616b3557066eb342090f 100644 (file)
@@ -3666,6 +3666,9 @@ unsigned long *colormasks;
     char *fval = (char *) 0;
     boolean reset_state = NO_RESET;
 
+    if ((fldidx < BL_RESET) || (fldidx >= MAXBLSTATS))
+        return;
+
     if ((fldidx >= 0 && fldidx < MAXBLSTATS) && !status_activefields[fldidx])
         return;
 
@@ -3727,11 +3730,13 @@ unsigned long *colormasks;
     case BL_HUNGER:
         /* The core sends trailing blanks for some fields.
            Let's suppress the trailing blanks */
-        lastchar = eos(status_vals[fldidx]);
-        lastchar--;
-        while (*lastchar == ' ' && lastchar >= status_vals[fldidx]) {
-            *lastchar-- = '\0';
-            tty_status[NOW][fldidx].lth--;
+        if (tty_status[NOW][fldidx].lth > 0) {
+            lastchar = eos(status_vals[fldidx]);
+            lastchar--;
+            while (lastchar >= status_vals[fldidx] && *lastchar == ' ') {
+                *lastchar-- = '\0';
+                tty_status[NOW][fldidx].lth--;
+            }
         }
         break;
     case BL_TITLE: