mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
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)
This commit is contained in:
parent
67fb1bc8ed
commit
60f7eec450
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=214524
@ -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 @@ evalvar(char *p, int flag)
|
||||
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 @@ evalvar(char *p, int flag)
|
||||
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
|
||||
|
22
tools/regression/bin/sh/expansion/trim6.0
Normal file
22
tools/regression/bin/sh/expansion/trim6.0
Normal file
@ -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"
|
Loading…
Reference in New Issue
Block a user