svn commit: r293359 - in head/bin/sh: . tests/builtins

Jilles Tjoelker jilles at FreeBSD.org
Thu Jan 7 20:48:26 UTC 2016


Author: jilles
Date: Thu Jan  7 20:48:24 2016
New Revision: 293359
URL: https://svnweb.freebsd.org/changeset/base/293359

Log:
  sh: Ensure OPTIND=1 in subshell without forking does not affect outer env.
  
  Command substitutions containing a single simple command and here-document
  expansion are performed in a subshell environment, but may not fork. Any
  modified state of the shell environment should be restored afterward.
  
  The state that OPTIND=1 had been done was not saved and restored here.
  
  Note that the other parts of shellparam need not be saved and restored,
  since they are not modified in these situations (a fork is done before such
  modifications).

Added:
  head/bin/sh/tests/builtins/getopts10.0   (contents, props changed)
Modified:
  head/bin/sh/eval.c
  head/bin/sh/tests/builtins/Makefile

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Thu Jan  7 20:43:45 2016	(r293358)
+++ head/bin/sh/eval.c	Thu Jan  7 20:48:24 2016	(r293359)
@@ -496,10 +496,12 @@ exphere(union node *redir, struct arglis
 	struct jmploc *savehandler;
 	struct localvar *savelocalvars;
 	int need_longjmp = 0;
+	unsigned char saveoptreset;
 
 	redir->nhere.expdoc = "";
 	savelocalvars = localvars;
 	localvars = NULL;
+	saveoptreset = shellparam.reset;
 	forcelocal++;
 	savehandler = handler;
 	if (setjmp(jmploc.loc))
@@ -514,6 +516,7 @@ exphere(union node *redir, struct arglis
 	forcelocal--;
 	poplocalvars();
 	localvars = savelocalvars;
+	shellparam.reset = saveoptreset;
 	if (need_longjmp)
 		longjmp(handler->loc, 1);
 	INTON;
@@ -647,6 +650,7 @@ evalbackcmd(union node *n, struct backcm
 	struct jmploc jmploc;
 	struct jmploc *savehandler;
 	struct localvar *savelocalvars;
+	unsigned char saveoptreset;
 
 	result->fd = -1;
 	result->buf = NULL;
@@ -661,6 +665,7 @@ evalbackcmd(union node *n, struct backcm
 	if (is_valid_fast_cmdsubst(n)) {
 		savelocalvars = localvars;
 		localvars = NULL;
+		saveoptreset = shellparam.reset;
 		forcelocal++;
 		savehandler = handler;
 		if (setjmp(jmploc.loc)) {
@@ -671,6 +676,7 @@ evalbackcmd(union node *n, struct backcm
 				forcelocal--;
 				poplocalvars();
 				localvars = savelocalvars;
+				shellparam.reset = saveoptreset;
 				longjmp(handler->loc, 1);
 			}
 		} else {
@@ -681,6 +687,7 @@ evalbackcmd(union node *n, struct backcm
 		forcelocal--;
 		poplocalvars();
 		localvars = savelocalvars;
+		shellparam.reset = saveoptreset;
 	} else {
 		if (pipe(pip) < 0)
 			error("Pipe call failed: %s", strerror(errno));

Modified: head/bin/sh/tests/builtins/Makefile
==============================================================================
--- head/bin/sh/tests/builtins/Makefile	Thu Jan  7 20:43:45 2016	(r293358)
+++ head/bin/sh/tests/builtins/Makefile	Thu Jan  7 20:48:24 2016	(r293359)
@@ -95,6 +95,7 @@ FILES+=		getopts6.0
 FILES+=		getopts7.0
 FILES+=		getopts8.0 getopts8.0.stdout
 FILES+=		getopts9.0 getopts9.0.stdout
+FILES+=		getopts10.0
 FILES+=		hash1.0 hash1.0.stdout
 FILES+=		hash2.0 hash2.0.stdout
 FILES+=		hash3.0 hash3.0.stdout

Added: head/bin/sh/tests/builtins/getopts10.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/builtins/getopts10.0	Thu Jan  7 20:48:24 2016	(r293359)
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+set -- -x arg
+opt=not
+getopts x opt
+r1=$? OPTIND1=$OPTIND opt1=$opt
+: $(: $((OPTIND = 1)))
+getopts x opt
+r2=$? OPTIND2=$OPTIND
+[ "$r1" = 0 ] && [ "$OPTIND1" = 2 ] && [ "$opt1" = x ] && [ "$r2" != 0 ] &&
+	[ "$OPTIND2" = 2 ]


More information about the svn-src-head mailing list