]> granicus.if.org Git - nethack/commitdiff
more qbuf
authornethack.allison <nethack.allison>
Thu, 8 May 2003 11:19:16 +0000 (11:19 +0000)
committernethack.allison <nethack.allison>
Thu, 8 May 2003 11:19:16 +0000 (11:19 +0000)
Pat pointed out to me that there are other potential
qbuf overflows, so this adds a function to assist in
weeding them out.

include/extern.h
src/pickup.c

index 1234aa7a019e3d801719a54b5d0f0268d4efd2ee..0b1d7cf0248272401890d003f42f99949402f662 100644 (file)
@@ -1478,6 +1478,7 @@ E int NDECL(doloot);
 E int FDECL(use_container, (struct obj *,int));
 E int FDECL(loot_mon, (struct monst *,int *,boolean *));
 E int NDECL(dotip);
+E char *FDECL(safe_qbuf, (char *,unsigned,char *,char *,const char *));
 
 /* ### pline.c ### */
 
index ba54adc2a59bf0fce0ca1484d56291c88974727f..848706b7bc11228ad66a920b4f753fc73bd65a1a 100644 (file)
@@ -1122,18 +1122,15 @@ boolean telekinesis;
            } else {
                char qbuf[BUFSZ];
                long savequan = obj->quan;
-               unsigned textleft;
 
                obj->quan = *cnt_p;
                Strcpy(qbuf,
                        (next_encumbr > HVY_ENCUMBER) ? overloadmsg :
                        (next_encumbr > MOD_ENCUMBER) ? nearloadmsg :
                        moderateloadmsg);
-               textleft = QBUFSZ - (strlen(qbuf) + sizeof(" . Continue?"));
                Sprintf(eos(qbuf), " %s. Continue?",
-                       (strlen(doname(obj)) < textleft) ? doname(obj) :
-                       (strlen(simple_typename(obj->otyp)) < textleft) ?
-                       an(simple_typename(obj->otyp)) : something);
+                       safe_qbuf(qbuf, sizeof(" . Continue?"),
+                               doname(obj), an(simple_typename(obj->otyp)), something));
                obj->quan = savequan;
                switch (ynq(qbuf)) {
                case 'q':  result = -1; break;
@@ -1150,6 +1147,27 @@ boolean telekinesis;
     return result;
 }
 
+/* To prevent qbuf overflow in prompts use planA only
+ * if it fits, or planB if PlanA doesn't fit,
+ * finally using the fallback as a last resort.
+ * last_restort is expected to be very short.
+ */
+char *
+safe_qbuf(qbuf, padlength, planA, planB, last_resort)
+char *qbuf, *planA, *planB;
+const char *last_resort;
+unsigned padlength;
+{
+       unsigned textleft = QBUFSZ - (strlen(qbuf) + padlength);
+       if (strlen(last_resort) >= textleft) {
+               impossible("safe_qbuf: last_resort too large at %d characters.",
+                       strlen(last_resort));
+               return "";
+       }
+       return (strlen(planA) < textleft) ? planA :
+              (strlen(planB) < textleft) ? planB : last_resort;
+}
+
 /*
  * Pick up <count> of obj from the ground and add it to the hero's inventory.
  * Returns -1 if caller should break out of its loop, 0 if nothing picked