diff options
| author | Igor Burago <ib@iburago.org> | 2022-08-16 20:25:27 +0800 |
|---|---|---|
| committer | Dan Cross <crossd@gmail.com> | 2022-09-06 13:21:23 -0400 |
| commit | e4b913866b759d4744b8636ac73a8775447dd28e (patch) | |
| tree | c2b512c826d0460e7ec258bcfc485fefd0614428 /src/cmd | |
| parent | a4af25bc0da1777f91ea0ae2674a4e64c7d1c83e (diff) | |
plumber: fail on buffer exhaustion or runaway quotes in string expansion
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/plumb/rules.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/cmd/plumb/rules.c b/src/cmd/plumb/rules.c index 6e9b2c63..2cb4afe9 100644 --- a/src/cmd/plumb/rules.c +++ b/src/cmd/plumb/rules.c @@ -289,22 +289,35 @@ dollar(Exec *e, char *s, int *namelen) return variable(s, n); } +static void +ruleerror(char *msg) +{ + if(parsing){ + parsing = 0; + parseerror("%s", msg); + } + error("%s", msg); +} + /* expand one blank-terminated string, processing quotes and $ signs */ char* expand(Exec *e, char *s, char **ends) { char *p, *ep, *val; - int namelen, quoting; + int namelen, vallen, quoting, inputleft; p = ebuf; ep = ebuf+sizeof ebuf-1; quoting = 0; - while(p<ep && *s!='\0' && (quoting || (*s!=' ' && *s!='\t'))){ + for(;;){ + inputleft = (*s!='\0' && (quoting || (*s!=' ' && *s!='\t'))); + if(!inputleft || p==ep) + break; if(*s == '\''){ s++; if(!quoting) quoting = 1; - else if(*s == '\''){ + else if(*s == '\''){ *p++ = '\''; s++; }else @@ -321,12 +334,17 @@ expand(Exec *e, char *s, char **ends) *p++ = '$'; continue; } - if(ep-p < strlen(val)) - return "string-too-long"; + vallen = strlen(val); + if(ep-p < vallen) + break; strcpy(p, val); - p += strlen(val); + p += vallen; s += namelen; } + if(inputleft) + ruleerror("expanded string too long"); + else if(quoting) + ruleerror("runaway quoted string literal"); if(ends) *ends = s; *p = '\0'; @@ -336,11 +354,7 @@ expand(Exec *e, char *s, char **ends) void regerror(char *msg) { - if(parsing){ - parsing = 0; - parseerror("%s", msg); - } - error("%s", msg); + ruleerror(msg); } void |