Module Name:    src
Committed By:   kre
Date:           Tue Dec 11 13:31:20 UTC 2018

Modified Files:
        src/bin/sh: main.c parser.c parser.h sh.1

Log Message:
PR standards/42829

Implement parameter and arithmetic expansion of $ENV
before using it as the name of a file from which to
read startup commands for the shell.   This continues
to happen for all interactive shells, and non-interactive
shells for which the posix option is not set (-o posix).

On any actual error, or if an attempt is made to use
command substitution, then the value of ENV is used
unchanged as the file name.

The expansion complies with POSIX XCU 2.5.3, though that
only requires parameter expansion - arithmetic expansion
is an extension (but for us, it is much easier to do, than
not to do, and it allows some weird stuff, if you're so
inclined....)   Note that there is no ~ expansion (use $HOME).


To generate a diff of this commit:
cvs rdiff -u -r1.78 -r1.79 src/bin/sh/main.c
cvs rdiff -u -r1.158 -r1.159 src/bin/sh/parser.c
cvs rdiff -u -r1.26 -r1.27 src/bin/sh/parser.h
cvs rdiff -u -r1.211 -r1.212 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/main.c
diff -u src/bin/sh/main.c:1.78 src/bin/sh/main.c:1.79
--- src/bin/sh/main.c:1.78	Mon Dec  3 06:43:19 2018
+++ src/bin/sh/main.c	Tue Dec 11 13:31:20 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.78 2018/12/03 06:43:19 kre Exp $	*/
+/*	$NetBSD: main.c,v 1.79 2018/12/11 13:31:20 kre Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 19
 #if 0
 static char sccsid[] = "@(#)main.c	8.7 (Berkeley) 7/19/95";
 #else
-__RCSID("$NetBSD: main.c,v 1.78 2018/12/03 06:43:19 kre Exp $");
+__RCSID("$NetBSD: main.c,v 1.79 2018/12/11 13:31:20 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -202,20 +202,24 @@ main(int argc, char **argv)
 	if (argv[0] && argv[0][0] == '-') {
 		state = 1;
 		read_profile("/etc/profile");
-state1:
+ state1:
 		state = 2;
 		read_profile(".profile");
 	}
-state2:
+ state2:
 	state = 3;
 	if ((iflag || !posix) &&
 	    getuid() == geteuid() && getgid() == getegid()) {
+		struct stackmark env_smark;
+
+		setstackmark(&env_smark);
 		if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
 			state = 3;
-			read_profile(shinit);
+			read_profile(expandenv(shinit));
 		}
+		popstackmark(&env_smark);
 	}
-state3:
+ state3:
 	state = 4;
 	line_number = 1;	/* undo anything from profile files */
 
@@ -238,7 +242,7 @@ state3:
 		evalstring(minusc, sflag ? 0 : EV_EXIT);
 
 	if (sflag || minusc == NULL) {
-state4:	/* XXX ??? - why isn't this before the "if" statement */
+ state4:	/* XXX ??? - why isn't this before the "if" statement */
 		cmdloop(1);
 	}
 #if PROFILE
@@ -326,6 +330,9 @@ read_profile(const char *name)
 	int xflag_set = 0;
 	int vflag_set = 0;
 
+	if (*name == '\0')
+		return;
+
 	INTOFF;
 	if ((fd = open(name, O_RDONLY)) >= 0)
 		setinputfd(fd, 1);

Index: src/bin/sh/parser.c
diff -u src/bin/sh/parser.c:1.158 src/bin/sh/parser.c:1.159
--- src/bin/sh/parser.c:1.158	Sun Dec  9 17:33:38 2018
+++ src/bin/sh/parser.c	Tue Dec 11 13:31:20 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: parser.c,v 1.158 2018/12/09 17:33:38 christos Exp $	*/
+/*	$NetBSD: parser.c,v 1.159 2018/12/11 13:31:20 kre Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c	8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.158 2018/12/09 17:33:38 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.159 2018/12/11 13:31:20 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -2447,7 +2447,7 @@ getprompt(void *unused)
  * behaviour.
  */
 static const char *
-expandonstack(char *ps, int lineno)
+expandonstack(char *ps, int cmdsub, int lineno)
 {
 	union node n;
 	struct jmploc jmploc;
@@ -2465,9 +2465,13 @@ expandonstack(char *ps, int lineno)
 		setinputstring(ps, 1, lineno);
 
 		readtoken1(pgetc(), DQSYNTAX, 1);
-		if (backquotelist != NULL && !promptcmds)
-			result = "-o promptcmds not set: ";
-		else {
+		if (backquotelist != NULL) {
+			if (!cmdsub) 
+				result = ps;
+			else if (!promptcmds)
+				result = "-o promptcmds not set: ";
+		}
+		if (result == NULL) {
 			n.narg.type = NARG;
 			n.narg.next = NULL;
 			n.narg.text = wordtext;
@@ -2518,7 +2522,7 @@ expandstr(char *ps, int lineno)
 	 */
 	(void) stalloc(stackblocksize());
 
-	result = expandonstack(ps, lineno);
+	result = expandonstack(ps, 1, lineno);
 
 	if (__predict_true(result == stackblock())) {
 		size_t len = strlen(result) + 1;
@@ -2566,3 +2570,17 @@ expandstr(char *ps, int lineno)
 
 	return result;
 }
+
+/*
+ * and a simpler version, which does no $( ) expansions, for
+ * use during shell startup when we know we are not parsing,
+ * and so the stack is not in use - we can do what we like,
+ * and do not need to clean up (that's handled externally).
+ *
+ * Simply return the result, even if it is on the stack
+ */
+const char *
+expandenv(char *arg)
+{
+	return expandonstack(arg, 0, 0);
+}

Index: src/bin/sh/parser.h
diff -u src/bin/sh/parser.h:1.26 src/bin/sh/parser.h:1.27
--- src/bin/sh/parser.h:1.26	Mon Dec  3 06:40:26 2018
+++ src/bin/sh/parser.h	Tue Dec 11 13:31:20 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: parser.h,v 1.26 2018/12/03 06:40:26 kre Exp $	*/
+/*	$NetBSD: parser.h,v 1.27 2018/12/11 13:31:20 kre Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -77,6 +77,7 @@ int goodname(const char *);
 int isassignment(const char *);
 const char *getprompt(void *);
 const char *expandstr(char *, int);
+const char *expandenv(char *);
 
 struct HereDoc;
 union node;

Index: src/bin/sh/sh.1
diff -u src/bin/sh/sh.1:1.211 src/bin/sh/sh.1:1.212
--- src/bin/sh/sh.1:1.211	Tue Dec  4 14:03:30 2018
+++ src/bin/sh/sh.1	Tue Dec 11 13:31:20 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: sh.1,v 1.211 2018/12/04 14:03:30 kre Exp $
+.\"	$NetBSD: sh.1,v 1.212 2018/12/11 13:31:20 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 December 4, 2018
+.Dd December 11, 2018
 .Dt SH 1
 .\" everything except c o and s (keep them ordered)
 .ds flags abCEeFfhIiLmnpquVvXx
@@ -133,6 +133,8 @@ from the files
 .Pa /etc/profile
 and
 .Pa .profile
+in the user's home directory
+.Pq \&$HOME ,
 if they exist.
 If the environment variable
 .Ev ENV
@@ -143,9 +145,19 @@ of a login shell,
 and either the shell is interactive, or the
 .Cm posix
 option is not set,
-the shell next reads
-commands from the file named in
-.Ev ENV .
+the shell then performs parameter and arithmetic
+expansion on the value of
+.Ev ENV ,
+(these are described later)
+and then reads commands from the file name that results.
+If
+.Ev ENV
+contains a command substitution, or one of the
+other expansions fails, or if there are no expansions
+to expand, the value of
+.Ev ENV
+is used as the file name.
+.Pp
 Therefore, a user should place commands that are to be executed only at
 login time in the
 .Pa .profile
@@ -267,7 +279,8 @@ built-in (described later).
 .\"
 .It Fl a Em allexport
 Automatically export any variable to which a value is assigned
-while this flag is set.
+while this flag is set, unless the variable has been marked as
+not for export.
 .It Fl b Em notify
 Enable asynchronous notification of background job completion.
 (Not implemented.)
@@ -642,7 +655,8 @@ and does not need to be escaped, but may
 A newline following the escape character is treated as a line continuation,
 like the same sequence in a double quoted string,
 or when not quoted \(en
-the two characters, escape and newline, are removed from the input string.
+the two characters, the backslash escape and the newline,
+are removed from the input string.
 .Pp
 The following characters, when escaped, are converted in a
 manner similar to the way they would be in a string in the C language:

Reply via email to