From 50467a60b79683b4a6b85b8b3d46a699606cd7c5 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Thu, 8 May 2003 11:19:16 +0000 Subject: [PATCH] more qbuf 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 | 1 + src/pickup.c | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 1234aa7a0..0b1d7cf02 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 ### */ diff --git a/src/pickup.c b/src/pickup.c index ba54adc2a..848706b7b 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -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 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 -- 2.40.0