Author: jilles
Date: Fri Oct 29 19:34:57 2010
New Revision: 214524
URL: http://svn.freebsd.org/changeset/base/214524
Log:
  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@
    y="${v##*"$e"}"
    echo "$y"
  failed if $e contained the magic CTLESC byte.
  
  Exp-run done by:      pav (with some other sh(1) changes)

Added:
  head/tools/regression/bin/sh/expansion/trim6.0   (contents, props changed)
Modified:
  head/bin/sh/expand.c

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c        Fri Oct 29 19:17:07 2010        (r214523)
+++ head/bin/sh/expand.c        Fri Oct 29 19:34:57 2010        (r214524)
@@ -98,7 +98,7 @@ static struct arglist exparg;         /* holds 
 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, in
 
 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 strlo
                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 strlo
                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 strlo
 
        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 strlo
 
        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

Added: head/tools/regression/bin/sh/expansion/trim6.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/expansion/trim6.0      Fri Oct 29 19:34:57 
2010        (r214524)
@@ -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")
+...@$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"
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to