Fix read beyond end of conditional argument on missing operand

nstr_parse_val() interprets argument "" as (empty) identifier, then
returns a pointer right beyond the end of the string.

The argument points into player->argbuf[].  If another argument
follows the conditional, it gets appended to the conditional.  Else,
whatever's left there from previous commands gets appended.  If the
argument is at the very end of player->argbuf[], we parse beyond the
buffer, until we run into a syntax error, or a zero byte.

Since player->argbuf[] is followed by a bunch of pointers, a syntax
error is almost certain.  If we somehow manage to parse all the
pointers and player->lasttime, the runaway parse will end at
player->btused, because that's definitely zero when conditionals get
parsed.
This commit is contained in:
Markus Armbruster 2013-05-12 11:55:42 +02:00
parent 59a199c69d
commit 809a4e2321

View file

@ -77,6 +77,10 @@ nstr_comp(struct nscstr *np, int len, int type, char *str)
np = &dummy;
/* left operand */
if (!*cond) {
pr("%s -- %scondition expected\n", str, i ? "another " : "");
return -1;
}
tail = nstr_parse_val(cond, &np->lft);
lft_caidx = nstr_match_ca(&np->lft, ca);
@ -92,6 +96,10 @@ nstr_comp(struct nscstr *np, int len, int type, char *str)
++tail;
/* right operand */
if (!*tail) {
pr("%s -- operand expected\n", cond);
return -1;
}
tail = nstr_parse_val(tail, &np->rgt);
rgt_caidx = nstr_match_ca(&np->rgt, ca);
@ -313,7 +321,7 @@ nstr_parse_val(char *str, struct valstr *val)
}
/* funny character, interpret as identifier */
tail = str+1;
tail = CANT_HAPPEN(!*str) ? str : str + 1;
val->val_type = NSC_NOTYPE;
val->val_cat = NSC_ID;
val->val_as.str.base = str;