From f4269954c4911cd3bb833b559e70505a2019d567 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Sun, 9 Jun 2024 13:17:03 -0300 Subject: [PATCH 1/4] Fix variable expansion on expressions --- sh.dol.c | 2 -- sh.exp.c | 7 +++++++ sh.h | 1 + sh.sem.c | 12 ++++++------ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/sh.dol.c b/sh.dol.c index b083b54d..345d1733 100644 --- a/sh.dol.c +++ b/sh.dol.c @@ -54,8 +54,6 @@ static Char *Dcp, *const *Dvp; /* Input vector for Dreadc */ #define unDgetC(c) Dpeekc = c -#define QUOTES (_QF|_QB|_ESC) /* \ ' " ` */ - /* * The following variables give the information about the current * $ expansion, recording the current word position, the remaining diff --git a/sh.exp.c b/sh.exp.c index f291a59d..65923de5 100644 --- a/sh.exp.c +++ b/sh.exp.c @@ -579,6 +579,13 @@ exp6(Char ***vp, int ignore) etraci("exp6 {} status", getstatus(), vp); return putn(getstatus() == 0); } + for (cp = **vp; *cp; cp++) + if (cmap(*cp, _DOL | QUOTES)) { + (*vp)++; + if (ignore & TEXP_IGNORE) + return Strsave(STRNULL); + return Dfix1(cp); + } if (isa(**vp, ANYOP)) return (Strsave(STRNULL)); cp = *(*vp)++; diff --git a/sh.h b/sh.h index 19bf10d6..6feaf5ec 100644 --- a/sh.h +++ b/sh.h @@ -1305,5 +1305,6 @@ extern int filec; #define TEXP_IGNORE 1 /* in ignore, it means to ignore value, just parse */ #define TEXP_NOGLOB 2 /* in ignore, it means not to globone */ +#define QUOTES (_QB|_QF|_ESC) /* \ " ' ` */ #endif /* _h_sh */ diff --git a/sh.sem.c b/sh.sem.c index 0674a2e3..f3e60add 100644 --- a/sh.sem.c +++ b/sh.sem.c @@ -83,7 +83,7 @@ void execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, int do_glob) { - int forked = 0; + int expr, forked = 0; const struct biltins * volatile bifunc; pid_t pid = 0; int pv[2]; @@ -188,7 +188,11 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) memmove(t->t_dcom[0], t->t_dcom[0] + 1, (Strlen(t->t_dcom[0] + 1) + 1) * sizeof (*t->t_dcom[0])); - if ((t->t_dflg & F_REPEAT) == 0) + if (!(expr = ((bifunc = isbfunc(t)) && + (bifunc->bfunct == doexit || + bifunc->bfunct == dolet || + bifunc->bfunct == doif || + bifunc->bfunct == dowhile)))) Dfix(t); /* $ " ' \ */ if (t->t_dcom[0] == 0) { return; @@ -290,10 +294,6 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, /* is it a command */ if (t->t_dtyp == NODE_COMMAND) { - /* - * Check if we have a builtin function and remember which one. - */ - bifunc = isbfunc(t); if (noexec) { /* * Continue for builtins that are part of the scripting language From 2e86c85b9383c20481d61a055f96139b46560c6f Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:41:08 -0300 Subject: [PATCH 2/4] Bug fixes --- sh.exp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sh.exp.c b/sh.exp.c index 65923de5..96f690f3 100644 --- a/sh.exp.c +++ b/sh.exp.c @@ -581,10 +581,16 @@ exp6(Char ***vp, int ignore) } for (cp = **vp; *cp; cp++) if (cmap(*cp, _DOL | QUOTES)) { - (*vp)++; - if (ignore & TEXP_IGNORE) + Char *buf; + + if (ignore & TEXP_IGNORE) { + (*vp)++; return Strsave(STRNULL); - return Dfix1(cp); + } + cleanup_push(cp = Dfix1(*(*vp)++), xfree); + buf = globone(cp, G_ERROR); + cleanup_until(cp); + return buf; } if (isa(**vp, ANYOP)) return (Strsave(STRNULL)); From 56d3a2c710e785193632f860a6b4202887ad2b3f Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Tue, 11 Jun 2024 01:23:22 -0300 Subject: [PATCH 3/4] Fix verbose mode --- sh.decls.h | 3 +++ sh.exp.c | 39 ++++++++++++++++++++++++++++++++++++--- sh.func.c | 6 +++++- sh.misc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 4 deletions(-) diff --git a/sh.decls.h b/sh.decls.h index a863fede..15b72bb4 100644 --- a/sh.decls.h +++ b/sh.decls.h @@ -300,6 +300,9 @@ extern int xopen (const char *, int, ...); extern ssize_t xread (int, void *, size_t); extern int xtcsetattr (int, int, const struct termios *); extern ssize_t xwrite (int, const void *, size_t); +extern int blkcmp (Char **, Char **); +extern void blkcmpfree (Char **, Char **); +extern void blkcmp_cleanup(void *); /* * sh.parse.c diff --git a/sh.exp.c b/sh.exp.c index 96f690f3..084ac2b3 100644 --- a/sh.exp.c +++ b/sh.exp.c @@ -180,7 +180,40 @@ sh_access(const Char *fname, int mode) tcsh_number_t expr(Char ***vp) { - return (exp0(vp, 0)); + Char **vpi, **vpc, *nblk[2], **blks[2]; + tcsh_number_t i; + int len; + + *blks = blks[1] = NULL; + cleanup_push(blks, blkcmp_cleanup); + len = blklen(*vp) + 1; + vpi = *vp; + vpc = *blks = xmalloc(sizeof **blks * len); + nblk[1] = NULL; + while (*vpi) { + *nblk = Strsave(*vpi++); + (void) blkcpy(vpc++, nblk); + } + blks[1] = blkcpy(xmalloc(sizeof *blks[1] * len), vpc = *blks); + i = exp0(&vpc, 0); + *vp += --len - blklen(vpc); + { + Char **nvp; + + len -= blklen(vpc); + vpi = *blks; + cleanup_push(nvp = xmalloc(sizeof *nvp * (len + 1)), xfree); + while (vpi != vpc) { + *nblk = *vpi++; + (void) blkcpy(nvp++, nblk); + } + nvp -= len; + xechoit(nvp); + cleanup_until(nvp); + } + cleanup_until(blks); + + return i; } tcsh_number_t @@ -587,8 +620,8 @@ exp6(Char ***vp, int ignore) (*vp)++; return Strsave(STRNULL); } - cleanup_push(cp = Dfix1(*(*vp)++), xfree); - buf = globone(cp, G_ERROR); + cleanup_push(cp = Dfix1(**vp), xfree); + *(*vp)++ = Strsave(buf = globone(cp, G_ERROR)); cleanup_until(cp); return buf; } diff --git a/sh.func.c b/sh.func.c index a9c0dd6f..eae51639 100644 --- a/sh.func.c +++ b/sh.func.c @@ -131,7 +131,11 @@ func(struct command *t, const struct biltins *bp) { int i; - xechoit(t->t_dcom); + if (bp->bfunct != doexit && + bp->bfunct != dolet && + bp->bfunct != doif && + bp->bfunct != dowhile) + xechoit(t->t_dcom); setname(bp->bname); i = blklen(t->t_dcom) - 1; if (i < bp->minargs) diff --git a/sh.misc.c b/sh.misc.c index 0b6b3370..d701aff4 100644 --- a/sh.misc.c +++ b/sh.misc.c @@ -721,3 +721,53 @@ xwrite(int fildes, const void *buf, size_t nbyte) while ((res = write(fildes, buf, nbyte)) == -1 && errno == EINTR); return res; } + +int +blkcmp(Char **fb, Char **sb) +{ + if (blklen(fb) != blklen(sb)) + return 1; + while (*fb == *sb++) + if (*fb++ == NULL) + return 0; + return 1; +} + +void +blkcmpfree(Char **fb, Char **sb) +{ + if (fb == NULL) + fb = xcalloc(1, sizeof *fb); + if (sb == NULL) + sb = xcalloc(1, sizeof *sb); + if (blkcmp(fb, sb)) { + Char **ofb, **osb; + + for (ofb = fb, osb = sb; *fb && *sb; fb++, sb++) { + if (*fb != *sb) + xfree(*sb); + xfree(*fb); + } + + while (*fb) + xfree(*fb++); + xfree(ofb); + while (*sb) + xfree(*sb++); + xfree(osb); + + return; + } + + blkfree(fb); + xfree(sb); +} + +void +blkcmp_cleanup(void *xblks) +{ + Char **(*blks)[2]; + + blks = xblks; + blkcmpfree(**blks, (*blks)[1]); +} From 284cef8bdf8fb3660d55254fef5f8f9082192cd4 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Wed, 12 Jun 2024 23:49:00 -0300 Subject: [PATCH 4/4] blkcmpfree: more careful not to re-free --- sh.misc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sh.misc.c b/sh.misc.c index d701aff4..fa35edea 100644 --- a/sh.misc.c +++ b/sh.misc.c @@ -751,7 +751,8 @@ blkcmpfree(Char **fb, Char **sb) while (*fb) xfree(*fb++); - xfree(ofb); + if (ofb != osb) + xfree(ofb); while (*sb) xfree(*sb++); xfree(osb); @@ -759,8 +760,9 @@ blkcmpfree(Char **fb, Char **sb) return; } + if (fb != sb) + xfree(sb); blkfree(fb); - xfree(sb); } void