Module Name: src Committed By: kre Date: Fri Oct 6 21:09:45 UTC 2017
Modified Files: src/bin/sh: expand.c sh.1 Log Message: Three fixes and a change to ~ expansions 1. A serious bug introduced 3 1/2 months ago (approx) (rev 1.116) which broke all but the simple cases of ~ expansions is fixed (amazingly, given the magnitude of this problem, no-one noticed!) 2. An ancient bug (probably from when ~ expansion was first addedin 1994, and certainly is in NetBSD-6 vintage shells) where ${UnSeT:-~} (and similar) does not expand the ~ is fixed (note that ${UnSeT:-~/} does expand, this should give a clue to the cause of the problem. 3. A fix/change to make the effects of ~ expansions on ${UnSeT:=whatever} identical to those in UnSeT=whatever In particular, with HOME=/foo ${UnSeT:=~:~} now assigns, and expands to, /foo:/foo rather than ~:~ just as VAR=~:~ assigns /foo:/foo to VAR. Note this is even after the previous fix (ie: appending a '/' would not change the results here.) It is hard to call this one a bug fix for certain (though I believe it is) as many other shells also produce different results for the ${V:=...} expansions than they do for V=... (though not all the same as we did). POSIX is not clear about this, expanding ~ after : in VAR=whatever assignments is clear, whether ${U:=whatever} assignments should be treated the same way is not stated, one way or the other. 4. Change to make ':' terminate the user name in a ~ expansion in all cases, not only in assignments. This makes sense, as ':' is one character that cannot occur in user names, no matter how otherwise weird they become. bash (incl in posix mode) ksh93 and bosh all act this way, whereas most other shells (and POSIX) do not. Because this is clearly an extension to POSIX, do this one only when not in posix mode (not set -o posix). To generate a diff of this commit: cvs rdiff -u -r1.120 -r1.121 src/bin/sh/expand.c cvs rdiff -u -r1.166 -r1.167 src/bin/sh/sh.1 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/expand.c diff -u src/bin/sh/expand.c:1.120 src/bin/sh/expand.c:1.121 --- src/bin/sh/expand.c:1.120 Mon Aug 21 13:20:49 2017 +++ src/bin/sh/expand.c Fri Oct 6 21:09:45 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: expand.c,v 1.120 2017/08/21 13:20:49 kre Exp $ */ +/* $NetBSD: expand.c,v 1.121 2017/10/06 21:09:45 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #else -__RCSID("$NetBSD: expand.c,v 1.120 2017/08/21 13:20:49 kre Exp $"); +__RCSID("$NetBSD: expand.c,v 1.121 2017/10/06 21:09:45 kre Exp $"); #endif #endif /* not lint */ @@ -361,6 +361,7 @@ exptilde(const char *p, int flag) #endif setstackmark(&smark); + (void) grabstackstr(expdest); user = stackblock(); /* we will just borrow top of stack */ while ((c = *++p) != '\0') { @@ -372,16 +373,16 @@ exptilde(const char *p, int flag) case CTLARI: /* just leave original unchanged */ case CTLENDARI: case CTLQUOTEMARK: - case CTLENDVAR: case '\n': popstackmark(&smark); return (startp); case CTLNONL: continue; case ':': - if (flag & EXP_VARTILDE) + if (!posix || flag & EXP_VARTILDE) goto done; break; + case CTLENDVAR: case '/': goto done; } @@ -682,7 +683,7 @@ subevalvar(const char *p, const char *st herefd = -1; VTRACE(DBG_EXPAND, ("subevalvar(%d) \"%.20s\" ${%.*s} sloc=%d vf=%x\n", subtype, p, p-str, str, startloc, varflags)); - argstr(p, EXP_TILDE); + argstr(p, subtype == VSASSIGN ? EXP_VARTILDE : EXP_TILDE); STACKSTRNUL(expdest); herefd = saveherefd; argbackq = saveargbackq; Index: src/bin/sh/sh.1 diff -u src/bin/sh/sh.1:1.166 src/bin/sh/sh.1:1.167 --- src/bin/sh/sh.1:1.166 Sun Aug 27 20:37:59 2017 +++ src/bin/sh/sh.1 Fri Oct 6 21:09:45 2017 @@ -1,4 +1,4 @@ -.\" $NetBSD: sh.1,v 1.166 2017/08/27 20:37:59 wiz Exp $ +.\" $NetBSD: sh.1,v 1.167 2017/10/06 21:09:45 kre Exp $ .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -31,7 +31,7 @@ .\" .\" @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" -.Dd August 20, 2017 +.Dd October 6, 2017 .Dt SH 1 .\" everything except c o and s (keep them ordered) .ds flags abCEeFfhIiLmnpquVvx @@ -477,6 +477,10 @@ opened using the built-in command are passed on to utilities executed .Dq ( yes in posix mode), +whether a colon (:) terminates the user name in tilde (~) expansions +other than in assignment statements +.Dq ( no +in posix mode), and whether the shell treats an empty brace-list compound statement as a syntax error (expected by POSIX) or permits it. @@ -1555,14 +1559,22 @@ substitution, or arithmetic evaluation. .Ss Tilde Expansion (substituting a user's home directory) A word beginning with an unquoted tilde character (~) is subjected to tilde expansion. -All the following characters in the word up to -a slash (/) or the end of the word are treated as a user name -and are replaced with the named user's home directory. +Provided all of the subsequent characters in the word are unquoted +up to an unquoted slash (/) +or when in an assignment or not in posix mode, an unquoted colon (:), +or if neither of those appear, the end of the word, +they are treated as a user name +and are replaced with the pathname of the named user's home directory. If the user name is missing (as in .Pa ~/foobar ) , the tilde is replaced with the value of the .Va HOME variable (the current user's home directory). +.Pp +In variable assignments, +an unquoted tilde immediately after the assignment operator (=), and +each unquoted tilde immediately after an unquoted colon in the value +to be assigned is also subject to tilde expansion as just stated. .Ss Parameter Expansion The format for parameter expansion is as follows: .Pp