aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorIgor Burago <ib@iburago.org>2022-08-16 20:25:27 +0800
committerDan Cross <crossd@gmail.com>2022-09-06 13:21:23 -0400
commite4b913866b759d4744b8636ac73a8775447dd28e (patch)
treec2b512c826d0460e7ec258bcfc485fefd0614428 /src/cmd
parenta4af25bc0da1777f91ea0ae2674a4e64c7d1c83e (diff)
plumber: fail on buffer exhaustion or runaway quotes in string expansion
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/plumb/rules.c36
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