1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix wrong syntax error upon process substitution after redirection

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: https://github.com/ksh93/ksh/issues/418
This commit is contained in:
Martijn Dekker 2022-07-05 13:01:26 +02:00
parent 8a0920ea0a
commit 06e56251b9
4 changed files with 44 additions and 1 deletions

View file

@ -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;