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.
This commit is contained in:
@@ -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 ### */
|
||||
|
||||
|
||||
28
src/pickup.c
28
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 <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
|
||||
|
||||
Reference in New Issue
Block a user