]> granicus.if.org Git - nethack/commitdiff
Fix: crash when appending to long engraving
authorMichael Meyer <me@entrez.cc>
Thu, 22 Jul 2021 00:07:28 +0000 (20:07 -0400)
committerPasi Kallinen <paxed@alt.org>
Wed, 28 Jul 2021 13:33:25 +0000 (16:33 +0300)
If an engraving was appended to repeatedly, it could eventually exceed
BUFSZ and cause a crash.  Add some checks to prevent this from happening
and inform the player when she runs out of space to engrave on a
particular square.

src/engrave.c

index b47eb790b88489711c1560f2ffbbfa4589222f59..da5e50510e0978f08da4e35764a591313ce59fb5 100644 (file)
@@ -994,6 +994,9 @@ doengrave(void)
                     You("will overwrite the current message.");
                 eow = TRUE;
             }
+        } else if (oep && (int) strlen(oep->engr_txt) >= BUFSZ - 1) {
+            There("is no room to add anything else here.");
+            return 1;
         }
     }
 
@@ -1120,7 +1123,7 @@ engrave(void)
     boolean dulling_wep, marker;
     char *endc; /* points at character 1 beyond the last character to engrave
                    this action */
-    int i;
+    int i, space_left;
 
     if (g.context.engraving.pos.x != u.ux
         || g.context.engraving.pos.y != u.uy) { /* teleported? */
@@ -1248,6 +1251,18 @@ engrave(void)
 
     /* actions that happen at the end of every engraving action go here */
 
+    Strcpy(buf, "");
+    oep = engr_at(u.ux, u.uy);
+    if (oep) /* add to existing engraving */
+        Strcpy(buf, oep->engr_txt);
+
+    space_left = sizeof buf - (int) strlen(buf) - 1;
+    if (endc - g.context.engraving.nextc > space_left) {
+        You("run out of room to write.");
+        endc = g.context.engraving.nextc + space_left;
+        truncate = TRUE;
+    }
+
     /* If the stylus did wear out mid-engraving, truncate the input so that we
      * can't go any further. */
     if (truncate && *endc != '\0') {
@@ -1260,12 +1275,8 @@ engrave(void)
         truncate = FALSE;
     }
 
-    Strcpy(buf, "");
-    oep = engr_at(u.ux, u.uy);
-    if (oep) /* add to existing engraving */
-        Strcpy(buf, oep->engr_txt);
     (void) strncat(buf, g.context.engraving.nextc,
-                   endc - g.context.engraving.nextc);
+                   min(space_left, endc - g.context.engraving.nextc));
     make_engr_at(u.ux, u.uy, buf, g.moves - g.multi, g.context.engraving.type);
 
     if (*endc) {