(getpath): Fix buffer overflow. Remote hole in commands bomb, drop,

fly, para, reco, sail, sweep.  Old code also screwed up when
getstring() failed, unless player->aborted.  Fixed code is still ugly
and cries for a rewrite.
This commit is contained in:
Markus Armbruster 2005-09-25 18:55:55 +00:00
parent 72c623ee92
commit 85a64e9fef

View file

@ -92,6 +92,7 @@ char *
getpath(char *buf, char *arg, coord x, coord y, int onlyown, getpath(char *buf, char *arg, coord x, coord y, int onlyown,
int showdes, int destinations) int showdes, int destinations)
{ {
char buf2[1024];
char *p = buf; char *p = buf;
char *bp; char *bp;
char prompt[128]; char prompt[128];
@ -115,30 +116,28 @@ getpath(char *buf, char *arg, coord x, coord y, int onlyown,
more: more:
while (*p) { while (*p) {
if (sarg_xy(p, &dx, &dy)) { if (sarg_xy(p, &dx, &dy)) {
bp = 0; bp = NULL;
if (destinations == P_NONE) { if (destinations == P_NONE) {
pr("Destination sectors not allowed here!\n"); pr("Destination sectors not allowed here!\n");
*p = 0;
} }
if (getsect(dx, dy, &dsect)) { if (getsect(dx, dy, &dsect)) {
if (destinations == P_WALKING) { if (destinations == P_WALKING) {
bp = BestLandPath(p, &sect, &dsect, bp = BestLandPath(buf2, &sect, &dsect,
&mv_cost, MOB_ROAD); &mv_cost, MOB_ROAD);
} else if (destinations == P_FLYING) { } else if (destinations == P_FLYING) {
bp = BestAirPath(p, nx, ny, dx, dy); bp = BestAirPath(buf2, nx, ny, dx, dy);
} }
} else { } else {
pr("Invalid destination sector!\n"); pr("Invalid destination sector!\n");
*p = 0;
} }
if (bp) { if (bp && p + strlen(bp) + 1 < buf + MAX_PATH_LEN) {
strcpy(p, bp);
pr("Using best path '%s'\n", p); pr("Using best path '%s'\n", p);
pr("Using total path '%s'\n", buf); pr("Using total path '%s'\n", buf);
return buf; return buf;
} else { } else {
pr("Can't get to %s from here!\n", pr("Can't get to %s from here!\n",
xyas(dx, dy, player->cnum)); xyas(dx, dy, player->cnum));
*p = 0;
} }
break; break;
} }
@ -146,14 +145,12 @@ getpath(char *buf, char *arg, coord x, coord y, int onlyown,
if (dir < 0) { if (dir < 0) {
pr("\"%c\" is not legal...", *p); pr("\"%c\" is not legal...", *p);
direrr("'%c' to stop\n", NULL, NULL); direrr("'%c' to stop\n", NULL, NULL);
*p = 0;
break; break;
} }
nx = x + diroff[dir][0]; nx = x + diroff[dir][0];
ny = y + diroff[dir][1]; ny = y + diroff[dir][1];
getsect(nx, ny, &sect); getsect(nx, ny, &sect);
if (onlyown && sect.sct_own != player->cnum) { if (onlyown && sect.sct_own != player->cnum) {
*p = 0;
pr("You don't own %s; you can't go there!\n", pr("You don't own %s; you can't go there!\n",
xyas(nx, ny, player->cnum)); xyas(nx, ny, player->cnum));
break; break;
@ -162,12 +159,7 @@ getpath(char *buf, char *arg, coord x, coord y, int onlyown,
p[1] = 0; p[1] = 0;
return buf; return buf;
} }
if (++p - buf == MAX_PATH_LEN) { ++p;
pr("Path length may not exceed %d.\n", MAX_PATH_LEN);
pr("Aborting...\n");
*buf = 0;
return buf;
}
x = nx; x = nx;
y = ny; y = ny;
} }
@ -180,12 +172,18 @@ getpath(char *buf, char *arg, coord x, coord y, int onlyown,
sprintf(prompt, "<%d: %s> ", (int)(p - buf), sprintf(prompt, "<%d: %s> ", (int)(p - buf),
xyas(x, y, player->cnum)); xyas(x, y, player->cnum));
} }
if (!(bp = getstring(prompt, p)) || !*bp) { bp = getstring(prompt, buf2);
if (player->aborted) if (bp && p + strlen(bp) + 1 >= buf + MAX_PATH_LEN) {
*buf = 0; pr("Path length may not exceed %d.\n", MAX_PATH_LEN);
return buf; pr("Aborting...\n");
bp = NULL;
} }
if (!bp)
return NULL;
strcpy(p, bp);
if (*bp)
goto more; goto more;
return buf;
} }
/* /*