diff options
author | jilles <jilles@FreeBSD.org> | 2010-10-28 22:34:49 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2010-10-28 22:34:49 +0000 |
commit | 6f54496b1660e6b4fd963cbd53a65890e2eaa8d4 (patch) | |
tree | 2f18c22be103c9782bf005a232148a34a49dc0bd | |
parent | 07e9b6a42f3f0bfbd8d8639ce46cf42a1c275a3a (diff) | |
download | FreeBSD-src-6f54496b1660e6b4fd963cbd53a65890e2eaa8d4.zip FreeBSD-src-6f54496b1660e6b4fd963cbd53a65890e2eaa8d4.tar.gz |
sh: Only accept a '}' inside ${v+-=?...} if double-quote state matches.
If double-quote state does not match, treat the '}' literally.
This ensures double-quote state remains the same before and after a
${v+-=?...} which helps with expand.c.
It makes things like
${foo+"\${bar}"}
which I have seen in the wild work as expected.
Exp-run done by: pav (with some other sh(1) changes)
-rw-r--r-- | bin/sh/parser.c | 8 | ||||
-rw-r--r-- | tools/regression/bin/sh/expansion/plus-minus5.0 | 31 |
2 files changed, 35 insertions, 4 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 5c0d2b1..07e6e72 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1233,12 +1233,12 @@ readtoken1(int firstc, char const *initialsyntax, char *eofmark, int striptabs) break; case CENDVAR: /* '}' */ if (level > 0 && - (state[level].category == TSTATE_VAR_OLD || + ((state[level].category == TSTATE_VAR_OLD && + state[level].syntax == + state[level - 1].syntax) || (state[level].category == TSTATE_VAR_NEW && state[level].syntax == BASESYNTAX))) { - if (state[level].category == TSTATE_VAR_OLD) - state[level - 1].syntax = state[level].syntax; - else + if (state[level].category == TSTATE_VAR_NEW) newvarnest--; level--; USTPUTC(CTLENDVAR, out); diff --git a/tools/regression/bin/sh/expansion/plus-minus5.0 b/tools/regression/bin/sh/expansion/plus-minus5.0 new file mode 100644 index 0000000..0b25e53 --- /dev/null +++ b/tools/regression/bin/sh/expansion/plus-minus5.0 @@ -0,0 +1,31 @@ +# $FreeBSD$ + +e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}' +h='##' +failures='' +ok='' + +testcase() { + code="$1" + expected="$2" + oIFS="$IFS" + eval "$code" + IFS='|' + result="$#|$*" + IFS="$oIFS" + if [ "x$result" = "x$expected" ]; then + ok=x$ok + else + failures=x$failures + echo "For $code, expected $expected actual $result" + fi +} + +testcase 'set -- ${e:-"{x}"}' '1|{x}' +testcase 'set -- "${e:-"{x}"}"' '1|{x}' +testcase 'set -- ${h+"{x}"}' '1|{x}' +testcase 'set -- "${h+"{x}"}"' '1|{x}' +testcase 'set -- ${h:-"{x}"}' '1|##' +testcase 'set -- "${h:-"{x}"}"' '1|##' + +test "x$failures" = x |