-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spurious syntax error on process substitution following redirection #418
Comments
Related: #215. Perhaps that bug can be fixed along with this one, once someone figures out the mystical inner workings of the shell parser. |
The problem appears to be that, after a redirection, the initial
|
The problem is actually in parse.c, not in lex.c. The process substitution is misparsed as a redirection due to |
This is the best I can come up with, I've been unable to break it: diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c
index 9d290ef4f..17a714218 100644
--- a/src/cmd/ksh93/sh/parse.c
+++ b/src/cmd/ksh93/sh/parse.c
@@ -48,6 +48,7 @@ static Shnode_t *makeparent(Lex_t*, int, Shnode_t*);
static Shnode_t *makelist(Lex_t*, int, Shnode_t*, Shnode_t*);
static struct argnod *qscan(struct comnod*, int);
static struct ionod *inout(Lex_t*,struct ionod*, int);
+static char inout_found_procsub;
static Shnode_t *sh_cmd(Lex_t*,int,int);
static Shnode_t *term(Lex_t*,int);
static Shnode_t *list(Lex_t*,int);
@@ -1583,6 +1584,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
lexp->token = tok = 0;
if((tok==IPROCSYM || tok==OPROCSYM))
{
+ procsub:
argp = process_sub(lexp,tok);
argno = -1;
*argtail = argp;
@@ -1655,6 +1657,8 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
}
else
t->comio = io = inout(lexp,(struct ionod*)0,0);
+ if(inout_found_procsub)
+ goto procsub;
}
}
*argtail = 0;
@@ -1753,6 +1757,9 @@ static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
Stk_t *stkp = sh.stk;
char *iovname=0;
register int errout=0;
+ /* return if a process substitution is found without a redirection */
+ if(inout_found_procsub = (token==IPROCSYM || token==OPROCSYM))
+ return(lastio);
if(token==IOVNAME)
{
iovname=lexp->arg->argval+1; |
Grammatically, redirections may occur anywhere within a command line and are removed after processing them, whereas a process substitution (<(commandlist) or >(commandlist)) is replaced by a file name which should be treated as just another simple word. So the following should not be a syntax error: $ cat </dev/null <(true) -ksh: syntax error: `)' unexpected $ cat </dev/null >(true) -ksh: syntax error: `)' unexpected $ cat >/dev/null <(true) -ksh: syntax error: `)' unexpected $ cat >/dev/null >(true) -ksh: syntax error: `)' unexpected This bug is in every ksh93 version. The problem is in the parser (parse.c). The process substitution is misparsed as a redirection due to inout() recursively parsing multiple redirections without recognising process substitutions. inout() is mistaking '<(' for '<' and '>(' for '>', which explains the incorrect syntax error. This also causes the following to fail to detect a syntax error: $ cat >&1 <(README.md [the contents of README.md are shown] ...and other syntax errors detected in the wrong spot, for example: $ { true; } <(echo wrong) -ksh: syntax error: `wrong' unexpected which should be: -ksh: syntax error: `<(' unexpected src/cmd/ksh93/sh/parse.c: - Add global inout_found_procsub flag. - inout(): On encountering a process substitution, set this flag and return, otherwise clear the flag. - simple(): After calling inout(), check this flag and, if set, jump back to where process substitutions are parsed. Resolves: #418
Gramatically, redirections can occur anywhere within a command line, whereas a process substitution (
<(
commandlist)
or>(
commandlist)
) is replaced by a file name, so should be treated as just another simple word. So the following should not be a syntax error:This bug is in every ksh93 version.
The text was updated successfully, but these errors were encountered: