From 809a4e2321ca10cab0e35d9e84dab6a8d125095f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 12 May 2013 11:55:42 +0200 Subject: [PATCH] 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. --- src/lib/subs/nstr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/subs/nstr.c b/src/lib/subs/nstr.c index d94567b61..7ffb5712f 100644 --- a/src/lib/subs/nstr.c +++ b/src/lib/subs/nstr.c @@ -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; -- 2.43.0