Module Name: src Committed By: kre Date: Mon Mar 6 05:54:34 UTC 2023
Modified Files: src/bin/sh: expand.c Log Message: Adjust tilde expansion as will be documented in the forthcoming version of the POSIX standard (Issue 8). I believe we were already compliant with what is to be required, but POSIX is now encouraging (and will likely require in a later version) that if a tilde expansion produces a string which ends in a '/' and the '~' that was expanded is immediately followed by a '/' in the input word, that one of those two slashes be omitted. The worst (current) example of this is when HOME=/ and we expand ~/foo - previously producing //foo which is (in POSIX) a path with implementation defined semantics, and so not what we should be generating by accident. Change that, so now if the ~ prefix expansion ends in a '/' and there is a '/' following immediately after, the resulting word contains only one of those chars (in the example just given, we will now produce /foo instead). POSIX is also making it clear that the expansion that results from the tilde expansion is treated as quoted (not subject to pathname expansion, or field splitting, or any var/arith/command substitutions) and that if HOME="" the expansion of ~ must generate "" (not nothing). Our implementation did all of that already (though older versions used to treat an empty expansion of HOME the same as if HOME was unset - that was fixed some time ago). The actual modification made here is probably smaller than this log entry, and without added comments, certainly is! To generate a diff of this commit: cvs rdiff -u -r1.141 -r1.142 src/bin/sh/expand.c 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.141 src/bin/sh/expand.c:1.142 --- src/bin/sh/expand.c:1.141 Mon Nov 22 05:17:43 2021 +++ src/bin/sh/expand.c Mon Mar 6 05:54:34 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: expand.c,v 1.141 2021/11/22 05:17:43 kre Exp $ */ +/* $NetBSD: expand.c,v 1.142 2023/03/06 05:54:34 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.141 2021/11/22 05:17:43 kre Exp $"); +__RCSID("$NetBSD: expand.c,v 1.142 2023/03/06 05:54:34 kre Exp $"); #endif #endif /* not lint */ @@ -388,7 +388,7 @@ argstr(const char *p, int flag) STATIC const char * exptilde(const char *p, int flag) { - char c; + char c, last; const char *startp = p; struct passwd *pw; const char *home; @@ -457,15 +457,35 @@ exptilde(const char *p, int flag) * Posix XCU 2.6.1: The value of $HOME (for ~) or the initial * working directory from getpwnam() for ~user * Nothing there about "except if a null string". So do what it wants. + * In later drafts (to become Issue 8), it is even required that in + * this case, (where HOME='') a bare ~ expands to "" (which must not + * be reduced to nothing). */ - if (home == NULL /* || *home == '\0' */) { + last = '\0'; /* just in case *home == '\0' (already) */ + if (home == NULL) { CTRACE(DBG_EXPAND, (": returning unused \"%s\"\n", startp)); return startp; } while ((c = *home++) != '\0') { if ((quotes && NEEDESC(c)) || ISCTL(c)) STPUTC(CTLESC, expdest); STPUTC(c, expdest); + last = c; } + + /* + * If HOME (or whatver) ended in a '/' (last == '/'), and + * the ~prefix was terminated by a '/', then only keep one + * of them - since we already took the one from HOME, just + * skip over the one that ended the tilde prefix. + * + * Current (Issue 8) drafts say this is permitted, and recommend + * it - a later version of the standard will probably require it. + * This is to prevent ~/foo generating //foo when HOME=/ (and + * other cases like it, but that's the important one). + */ + if (last == '/' && *p == '/') + p++; + CTRACE(DBG_EXPAND, (": added %d \"%.*s\" returning \"%s\"\n", expdest - stackblock() - offs, expdest - stackblock() - offs, stackblock() + offs, p));