summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2010-10-29 19:34:57 +0000
committerjilles <jilles@FreeBSD.org>2010-10-29 19:34:57 +0000
commitaaa3347e35af4d5a78d7159ebddda1f06dbb2275 (patch)
treee746f39f7e9cc329381f8a5921f6d37f038dd8dc
parentfb52bdc70d3cbdbe376680788e56f06717e7630f (diff)
downloadFreeBSD-src-aaa3347e35af4d5a78d7159ebddda1f06dbb2275.zip
FreeBSD-src-aaa3347e35af4d5a78d7159ebddda1f06dbb2275.tar.gz
sh: Fix some issues with CTL* bytes and ${var#pat}.
subevalvar() incorrectly assumed that CTLESC bytes were present iff the expansion was quoted. However, they are present iff various processing such as word splitting is to be done later on. Example: v=@$e@$e@$e@ y="${v##*"$e"}" echo "$y" failed if $e contained the magic CTLESC byte. Exp-run done by: pav (with some other sh(1) changes)
-rw-r--r--bin/sh/expand.c27
-rw-r--r--tools/regression/bin/sh/expansion/trim6.022
2 files changed, 35 insertions, 14 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 13dc38a..200da3f 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -98,7 +98,7 @@ static struct arglist exparg; /* holds expanded arg list */
static void argstr(char *, int);
static char *exptilde(char *, int);
static void expbackq(union node *, int, int);
-static int subevalvar(char *, char *, int, int, int, int);
+static int subevalvar(char *, char *, int, int, int, int, int);
static char *evalvar(char *, int);
static int varisset(char *, int);
static void varvalue(char *, int, int, int);
@@ -526,7 +526,7 @@ expbackq(union node *cmd, int quoted, int flag)
static int
subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
- int varflags)
+ int varflags, int quotes)
{
char *startp;
char *loc = NULL;
@@ -571,12 +571,12 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
for (loc = startp; loc < str; loc++) {
c = *loc;
*loc = '\0';
- if (patmatch(str, startp, varflags & VSQUOTE)) {
+ if (patmatch(str, startp, quotes)) {
*loc = c;
goto recordleft;
}
*loc = c;
- if ((varflags & VSQUOTE) && *loc == CTLESC)
+ if (quotes && *loc == CTLESC)
loc++;
}
return 0;
@@ -585,14 +585,13 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
for (loc = str - 1; loc >= startp;) {
c = *loc;
*loc = '\0';
- if (patmatch(str, startp, varflags & VSQUOTE)) {
+ if (patmatch(str, startp, quotes)) {
*loc = c;
goto recordleft;
}
*loc = c;
loc--;
- if ((varflags & VSQUOTE) && loc > startp &&
- *(loc - 1) == CTLESC) {
+ if (quotes && loc > startp && *(loc - 1) == CTLESC) {
for (q = startp; q < loc; q++)
if (*q == CTLESC)
q++;
@@ -604,14 +603,13 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
case VSTRIMRIGHT:
for (loc = str - 1; loc >= startp;) {
- if (patmatch(str, loc, varflags & VSQUOTE)) {
+ if (patmatch(str, loc, quotes)) {
amount = loc - expdest;
STADJUST(amount, expdest);
return 1;
}
loc--;
- if ((varflags & VSQUOTE) && loc > startp &&
- *(loc - 1) == CTLESC) {
+ if (quotes && loc > startp && *(loc - 1) == CTLESC) {
for (q = startp; q < loc; q++)
if (*q == CTLESC)
q++;
@@ -623,12 +621,12 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
case VSTRIMRIGHTMAX:
for (loc = startp; loc < str - 1; loc++) {
- if (patmatch(str, loc, varflags & VSQUOTE)) {
+ if (patmatch(str, loc, quotes)) {
amount = loc - expdest;
STADJUST(amount, expdest);
return 1;
}
- if ((varflags & VSQUOTE) && *loc == CTLESC)
+ if (quotes && *loc == CTLESC)
loc++;
}
return 0;
@@ -779,7 +777,7 @@ record:
STPUTC('\0', expdest);
patloc = expdest - stackblock();
if (subevalvar(p, NULL, patloc, subtype,
- startloc, varflags) == 0) {
+ startloc, varflags, quotes) == 0) {
int amount = (expdest - stackblock() - patloc) + 1;
STADJUST(-amount, expdest);
}
@@ -790,7 +788,8 @@ record:
case VSASSIGN:
case VSQUESTION:
if (!set) {
- if (subevalvar(p, var, 0, subtype, startloc, varflags)) {
+ if (subevalvar(p, var, 0, subtype, startloc, varflags,
+ quotes)) {
varflags &= ~VSNUL;
/*
* Remove any recorded regions beyond
diff --git a/tools/regression/bin/sh/expansion/trim6.0 b/tools/regression/bin/sh/expansion/trim6.0
new file mode 100644
index 0000000..3f753c4
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/trim6.0
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+e=
+for i in 0 1 2 3; do
+ for j in 0 1 2 3 4 5 6 7; do
+ for k in 0 1 2 3 4 5 6 7; do
+ case $i$j$k in
+ 000) continue ;;
+ esac
+ e="$e\\$i$j$k"
+ done
+ done
+done
+e=$(printf "$e")
+v=@$e@$e@
+y=${v##*"$e"}
+yq="${v##*"$e"}"
+[ "$y" = @ ] || echo "error when unquoted in non-splitting context"
+[ "$yq" = @ ] || echo "error when quoted in non-splitting context"
+[ "${v##*"$e"}" = @ ] || echo "error when quoted in splitting context"
+IFS=
+[ ${v##*"$e"} = @ ] || echo "error when unquoted in splitting context"
OpenPOWER on IntegriCloud