Module Name:    src
Committed By:   kre
Date:           Mon May  9 20:36:07 UTC 2016

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

Log Message:
PR bin/48489 -- Shell "simple commands" are now not allowed to be
completely empty, they must have something (var assignment, redirect,
or command, or multiple of those) to avoid a syntax error.  This
matches the requirements of the grammar in the standard.   Correct the
parser (using FreeBSD's sh as a guide) and update the man page to
remove text that noted a couple of places this was previously OK.

OK christos@


To generate a diff of this commit:
cvs rdiff -u -r1.118 -r1.119 src/bin/sh/parser.c
cvs rdiff -u -r1.121 -r1.122 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/parser.c
diff -u src/bin/sh/parser.c:1.118 src/bin/sh/parser.c:1.119
--- src/bin/sh/parser.c:1.118	Tue May  3 03:16:55 2016
+++ src/bin/sh/parser.c	Mon May  9 20:36:07 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: parser.c,v 1.118 2016/05/03 03:16:55 kre Exp $	*/
+/*	$NetBSD: parser.c,v 1.119 2016/05/09 20:36:07 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.118 2016/05/03 03:16:55 kre Exp $");
+__RCSID("$NetBSD: parser.c,v 1.119 2016/05/09 20:36:07 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -498,20 +498,32 @@ TRACE(("expecting DO got %s %s\n", tokna
 			synexpect(TEND, 0);
 		checkkwd = 1;
 		break;
-	/* Handle an empty command like other simple commands.  */
+
 	case TSEMI:
-		/*
-		 * An empty command before a ; doesn't make much sense, and
-		 * should certainly be disallowed in the case of `if ;'.
-		 */
-		if (!redir)
-			synexpect(-1, 0);
 	case TAND:
 	case TOR:
+	case TPIPE:
 	case TNL:
 	case TEOF:
-	case TWORD:
 	case TRP:
+		/*
+		 * simple commands must have something in them,
+		 * either a word (which at this point includes a=b)
+		 * or a redirection.  If we reached the end of the
+		 * command (which one of these tokens indicates)
+		 * when we are just starting, and have not had a
+		 * redirect, then ...
+		 *
+		 * nb: it is still possible to end up with empty
+		 * simple commands, if the "command" is a var
+		 * expansion that produces nothing
+		 *	X= ; $X && $X
+		 * -->          &&
+		 * I am not sure if this is intended to be legal or not.
+		 */
+		if (!redir)
+			synexpect(-1, 0);
+	case TWORD:
 		tokpushback++;
 		n1 = simplecmd(rpp, redir);
 		goto checkneg;

Index: src/bin/sh/sh.1
diff -u src/bin/sh/sh.1:1.121 src/bin/sh/sh.1:1.122
--- src/bin/sh/sh.1:1.121	Mon Apr  4 13:05:56 2016
+++ src/bin/sh/sh.1	Mon May  9 20:36:07 2016
@@ -1,4 +1,4 @@
-.\"	$NetBSD: sh.1,v 1.121 2016/04/04 13:05:56 wiz Exp $
+.\"	$NetBSD: sh.1,v 1.122 2016/05/09 20:36:07 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 March 31, 2016
+.Dd May 9, 2016
 .Dt SH 1
 .ds flags abCEeFfhnuvxIimpqV
 .Os
@@ -330,11 +330,9 @@ in which case altering the
 flag has no effect.
 .It Fl h Em trackall
 Bind commands in functions to file system paths when the function is defined.
-.\" They can seek me here (that dreaded filesystem)
 When off,
 the file system is searched for commands each time the function is invoked.
 (Not implemented.)
-.\" then can seek me there (the filesystem, once again)
 .It Fl p Em nopriv
 Do not attempt to reset effective uid if it does not match uid.
 This is not set by default to help avoid incorrect usage by setuid
@@ -589,7 +587,6 @@ new process.
 Otherwise, if the command name doesn't match a function or built-in, the
 command is searched for as a normal program in the file system (as
 described in the next section).
-.\" But the damned elusive filesystem shall never be defeated!
 When a normal program is executed, the shell runs the program,
 passing the arguments and the environment to the program.
 If the program is not a normal executable file (i.e., if it does
@@ -757,14 +754,6 @@ writes
 .Dq baz
 and nothing else.
 This is not the way it works in C.
-Also, if you forget the left-hand side (for example when continuing lines but
-forgetting to use a backslash) it defaults to a true statement.
-This behavior is not useful and should not be relied upon.
-Similarly, if input to the
-.Nm
-reaches end of file immediately after one of these operators,
-it is assumed that a true statement follows.
-This behavior is also not useful and should not be relied upon.
 .Ss Flow-Control Constructs -- if, while, for, case
 The syntax of the if command is
 .Bd -literal -offset indent

Reply via email to