From 403e864ac84a08247f94a46a48fac83e039cd46f Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 6 Feb 2021 22:00:55 +0000 Subject: [PATCH] Disallow >;word and <>;word for 'redirect' (re: 7b59fb80, 7b82c338) The >;word and <>;word redirection operators cannot be used with the 'exec' builtin, but the 'redirect' builtin (which used to be an alias of 'command exec') permitted them. However, they do not have the documented effect of the added ';'. So this commit blocks those operators for 'redirect' as they are blocked for 'exec'. It also tweaks redirect's error message if a non-redirection argument is encountered. src/cmd/ksh93/sh/parse.c: simple(): - Set the lexp->inexec flag for SYSREDIR (redirect) as well as SYSEXEC (exec). This flag is checked for in sh_lex() (lex.c) to throw a syntax error if one of these two operators is used. src/cmd/ksh93/sh.1, src/cmd/ksh93/data/builtins.c: - Documentation tweaks. src/cmd/ksh93/sh/xec.c, src/cmd/ksh93/bltins/misc.c: - When 'redirect' gives an 'incorrect syntax' (e_badsyntax) error message, include the first word that was found not to be a valid redirection. This is simply the first argument, as redirections are removed from the arguments list. src/cmd/ksh93/tests/io.sh: - Update test to reflect new error message format. --- src/cmd/ksh93/bltins/misc.c | 2 +- src/cmd/ksh93/data/builtins.c | 11 ++++++----- src/cmd/ksh93/sh.1 | 16 ++++++++++------ src/cmd/ksh93/sh/parse.c | 2 +- src/cmd/ksh93/sh/xec.c | 3 ++- src/cmd/ksh93/tests/io.sh | 2 +- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/cmd/ksh93/bltins/misc.c b/src/cmd/ksh93/bltins/misc.c index 9d299d9a3..102d725d4 100644 --- a/src/cmd/ksh93/bltins/misc.c +++ b/src/cmd/ksh93/bltins/misc.c @@ -110,7 +110,7 @@ int b_exec(int argc,char *argv[], Shbltin_t *context) if(error_info.errors) errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); if(*argv[0]=='r' && argv[opt_info.index]) /* 'redirect' supports no args */ - errormsg(SH_DICT,ERROR_exit(2),e_badsyntax); + errormsg(SH_DICT,ERROR_exit(2),"%s: %s",e_badsyntax,argv[opt_info.index]); argv += opt_info.index; if(!*argv) return(0); diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index 9080b5a43..676c1286b 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -598,7 +598,7 @@ const char sh_optexec[] = "[+?Because \bexec\b is a special built-in command, any failure will cause the " "script or command line that invokes it to be aborted. This can be " "prevented by invoking \bexec\b from the \bcommand\b utility.]" -"[+SEE ALSO?\bcommand\b(1), \beval\b(1), \bredirect(1)\b]" +"[+SEE ALSO?\bcommand\b(1), \beval\b(1), \bredirect\b(1)]" ; const char sh_optexit[] = @@ -1447,7 +1447,7 @@ const char sh_optreadonly[] = ; const char sh_optredirect[] = -"[-1c?\n@(#)$Id: redirect (ksh 93u+m) 2020-08-08 $\n]" +"[-1c?\n@(#)$Id: redirect (ksh 93u+m) 2021-02-06 $\n]" "[--catalog?" SH_DICT "]" "[+NAME?redirect - open/close and duplicate file descriptors]" "[+DESCRIPTION?This command only accepts input/output redirections. " @@ -1455,9 +1455,10 @@ const char sh_optredirect[] = "to \b9\b using the standard redirection mechanism available to all " "commands, with the difference that the effect persists past the " "execution of the \bredirect\b command.]" -"[+?Any file descriptor numbers greater than \b2\b that are opened with this " - "mechanism are closed when invoking another program, unless " - "explicitly redirected to themselves as part of that invocation.]" +"[+?When invoking another program, file descriptors greater than \b2\b that " + "were opened with this mechanism are only passed on if they are " + "explicitly redirected to themselves as part of the invocation " + "(e.g. \b4>&4\b) or if the \bposix\b option is set.]" "[+?\bredirect\b cannot be invoked from a restricted shell to create " "files or to open a file for writing or appending.]" "\n" diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index c0d6df5a4..659979b4a 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -3403,7 +3403,9 @@ otherwise, delete the temporary file. .BI >; word cannot be used with the .IR exec -built-in. +and +.IR redirect +built-ins. .TP .BI >> word Use file @@ -3428,7 +3430,9 @@ is truncated to the offset at command completion. .BI <>; word cannot be used with the .IR exec -built-in. +and +.IR redirect +built-ins. .TP \f3<<\fP\*(OK\f3\-\fP\*(CK\f2word\fP The shell input is read up to a line that is the same as @@ -6854,11 +6858,11 @@ section above), with the difference that the effect persists past the execution of the .B redirect command. -Any file descriptor numbers greater than +When invoking another program, file descriptors greater than .B 2 -that are opened with this mechanism are closed when invoking another program, -unless they are explicitly redirected to themselves as part of that invocation -(e.g. \fB4>&4\fR) or the \fBposix\fR shell option is active. +that were opened with this mechanism are only passed on if they are explicitly +redirected to themselves as part of the invocation (e.g. \fB4>&4\fR) +or if the \fBposix\fR option is set. .TP \(dg \f3return\fP \*(OK \f2n\^\fP \*(CK Causes a shell diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c index 734d2b1d2..85546e5ed 100644 --- a/src/cmd/ksh93/sh/parse.c +++ b/src/cmd/ksh93/sh/parse.c @@ -1459,7 +1459,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io) } else if(np==SYSCOMMAND && !sh_isoption(SH_POSIX)) cmdarg++; - else if(np==SYSEXEC) + else if(np==SYSEXEC || np==SYSREDIR) lexp->inexec = 1; else if(np->nvalue.bfp==(Nambfp_f)b_getopts) opt_get |= FOPTGET; diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 179d71d30..a3fba2907 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -1277,7 +1277,8 @@ int sh_exec(register const Shnode_t *t, int flags) if(!com[1]) type = 2; else - errormsg(SH_DICT,ERROR_exit(2),"redirect: %s",e_badsyntax); + errormsg(SH_DICT, ERROR_exit(2), "%s: %s: %s", + SYSREDIR->nvname, e_badsyntax, com[1]); else type = (execflg && !shp->subshell && !shp->st.trapcom[0]); shp->redir0 = 1; diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh index 0b0052653..468817bdc 100755 --- a/src/cmd/ksh93/tests/io.sh +++ b/src/cmd/ksh93/tests/io.sh @@ -528,7 +528,7 @@ actual=$(redirect 2>&- 3>&2; echo ok) [[ $actual == ok ]] || err_exit "redirection error in 'redirect' causes exit" # Test that 'redirect' does not accept non-redir args -expect=$'*: redirect: incorrect syntax\n status = 2' +expect=$'*: redirect: incorrect syntax: /dev/null/foo\n status = 2' actual=$( (redirect /dev/null/foo) 2>&1; echo " status = $?" ); [[ $actual == $expect ]] || err_exit 'redirect command accepts non-redirection argument' \ "(expected $(printf %q "$expect"), got $(printf %q "$actual"))"