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