From 8b220a611d5f0fdbffd638eadf0f7dd836712b9b Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Fri, 9 Apr 1999 15:23:48 +0000 Subject: When a variable expansion is enclosed in double quotes, the internal representation of the expression is quoted. Take care of this when doing pattern matching in conjunction with trimming. #!/bin/sh c=d:e; echo "${c%:e}" PR: NetBSD PR#7231 Noticed by: Havard Eidnes --- bin/sh/expand.c | 68 +++++++++++++++++++++++++++++++++++++++++++++------------ bin/sh/expand.h | 4 ++-- 2 files changed, 56 insertions(+), 16 deletions(-) (limited to 'bin') diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 757ff3ad4f68..8a6f03a0a77a 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #endif static const char rcsid[] = - "$Id: expand.c,v 1.23 1998/09/06 21:13:09 tegge Exp $"; + "$Id: expand.c,v 1.24 1998/09/13 19:24:57 tegge Exp $"; #endif /* not lint */ #include @@ -110,7 +110,7 @@ STATIC void expmeta __P((char *, char *)); STATIC void addfname __P((char *)); STATIC struct strlist *expsort __P((struct strlist *)); STATIC struct strlist *msort __P((struct strlist *, int)); -STATIC int pmatch __P((char *, char *)); +STATIC int pmatch __P((char *, char *, int)); STATIC char *cvtnum __P((int, char *)); STATIC int collate_range_cmp __P((int, int)); @@ -517,6 +517,7 @@ subevalvar(p, str, strloc, subtype, startloc, varflags) { char *startp; char *loc = NULL; + char *q; int c = 0; int saveherefd = herefd; struct nodelist *saveargbackq = argbackq; @@ -555,43 +556,65 @@ subevalvar(p, str, strloc, subtype, startloc, varflags) for (loc = startp; loc < str; loc++) { c = *loc; *loc = '\0'; - if (patmatch(str, startp)) { + if (patmatch(str, startp, varflags & VSQUOTE)) { *loc = c; goto recordleft; } *loc = c; + if ((varflags & VSQUOTE) && *loc == CTLESC) + loc++; } return 0; case VSTRIMLEFTMAX: - for (loc = str - 1; loc >= startp; loc--) { + for (loc = str - 1; loc >= startp;) { c = *loc; *loc = '\0'; - if (patmatch(str, startp)) { + if (patmatch(str, startp, varflags & VSQUOTE)) { *loc = c; goto recordleft; } *loc = c; + loc--; + if ((varflags & VSQUOTE) && loc > startp && + *(loc - 1) == CTLESC) { + for (q = startp; q < loc; q++) + if (*q == CTLESC) + q++; + if (q > loc) + loc--; + } } return 0; case VSTRIMRIGHT: - for (loc = str - 1; loc >= startp; loc--) { - if (patmatch(str, loc)) { + for (loc = str - 1; loc >= startp;) { + if (patmatch(str, loc, varflags & VSQUOTE)) { amount = loc - expdest; STADJUST(amount, expdest); return 1; } + loc--; + if ((varflags & VSQUOTE) && loc > startp && + *(loc - 1) == CTLESC) { + for (q = startp; q < loc; q++) + if (*q == CTLESC) + q++; + if (q > loc) + loc--; + } } return 0; case VSTRIMRIGHTMAX: for (loc = startp; loc < str - 1; loc++) { - if (patmatch(str, loc)) { + if (patmatch(str, loc, varflags & VSQUOTE)) { amount = loc - expdest; STADJUST(amount, expdest); return 1; } + if ((varflags & VSQUOTE) && *loc == CTLESC) + loc++; } return 0; @@ -1206,7 +1229,7 @@ expmeta(enddir, name) while (! int_pending() && (dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.' && ! matchdot) continue; - if (patmatch(start, dp->d_name)) { + if (patmatch(start, dp->d_name, 0)) { if (atend) { scopy(dp->d_name, enddir); addfname(expdir); @@ -1315,23 +1338,25 @@ msort(list, len) */ int -patmatch(pattern, string) +patmatch(pattern, string, squoted) char *pattern; char *string; + int squoted; /* string might have quote chars */ { #ifdef notdef if (pattern[0] == '!' && pattern[1] == '!') return 1 - pmatch(pattern + 2, string); else #endif - return pmatch(pattern, string); + return pmatch(pattern, string, squoted); } STATIC int -pmatch(pattern, string) +pmatch(pattern, string, squoted) char *pattern; char *string; + int squoted; { char *p, *q; char c; @@ -1343,12 +1368,16 @@ pmatch(pattern, string) case '\0': goto breakloop; case CTLESC: + if (squoted && *q == CTLESC) + q++; if (*q++ != *p++) return 0; break; case CTLQUOTEMARK: continue; case '?': + if (squoted && *q == CTLESC) + q++; if (*q++ == '\0') return 0; break; @@ -1359,14 +1388,21 @@ pmatch(pattern, string) if (c != CTLESC && c != CTLQUOTEMARK && c != '?' && c != '*' && c != '[') { while (*q != c) { + if (squoted && *q == CTLESC && + q[1] == c) + break; if (*q == '\0') return 0; + if (squoted && *q == CTLESC) + q++; q++; } } do { - if (pmatch(p, q)) + if (pmatch(p, q, squoted)) return 1; + if (squoted && *q == CTLESC) + q++; } while (*q++ != '\0'); return 0; case '[': { @@ -1394,6 +1430,8 @@ pmatch(pattern, string) } found = 0; chr = *q++; + if (squoted && chr == CTLESC) + chr = *q++; if (chr == '\0') return 0; c = *p++; @@ -1423,6 +1461,8 @@ pmatch(pattern, string) break; } dft: default: + if (squoted && *q == CTLESC) + q++; if (*q++ != c) return 0; break; @@ -1486,7 +1526,7 @@ casematch(pattern, val) argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); STPUTC('\0', expdest); p = grabstackstr(expdest); - result = patmatch(p, val); + result = patmatch(p, val, 0); popstackmark(&smark); return result; } diff --git a/bin/sh/expand.h b/bin/sh/expand.h index 18c16630b580..eec98852250e 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)expand.h 8.2 (Berkeley) 5/4/95 - * $Id: expand.h,v 1.6 1998/09/06 21:13:09 tegge Exp $ + * $Id: expand.h,v 1.7 1998/09/13 19:24:57 tegge Exp $ */ struct strlist { @@ -62,6 +62,6 @@ union node; void expandhere __P((union node *, int)); void expandarg __P((union node *, struct arglist *, int)); void expari __P((int)); -int patmatch __P((char *, char *)); +int patmatch __P((char *, char *, int)); void rmescapes __P((char *)); int casematch __P((union node *, char *)); -- cgit v1.2.3