Skip to content

Commit

Permalink
Improve fix for parentheses in param expansions (re: 5ed9ffd)
Browse files Browse the repository at this point in the history
The fix was incomplete: expansions using '?' (${var?w(ord},
${var:?wo)rd}) still did not tolerate parentheses in the word
as regular characters.

It was also possible to simplify the fix by making use of the
ST_BRACE (sh_lexstate7[]) state table. See data/lexstates.c and
include/lexstates.h.

src/cmd/ksh93/sh/lex.c: sh_lex(): case S_MOD1:
- The previous fix tested for modifier operator characters : - + =
  as part of the S_MOD2 case, though they are defined as S_MOD1 in
  the ST_BRACE state table. It only worked because of the
  fallthrough. And it turns out the S_MOD1 case already had a
  similar fix, though incomplete. The new fix effectively cancelled
  the old one out as any S_MOD1 character eventually led to
  'continue'. So it can be simplified by removing most of that
  code, without causing any change in behaviour. Only the mode
  change to the ST_QUOTE state table followed by 'continue' is
  necessary. This also fixes it for the '?' operator as that is
  also defined as S_MOD1 in the ST_BRACE state table.

src/cmd/ksh93/sh/macro.c:
- When skipping a ${...} expansion using sh_lexskip(), use the
  ST_QUOTE state table if the character c is an S_MOD1 modifier
  operator character. This makes it consistent with the S_MOD1
  handling in sh_lex().

src/cmd/ksh93/tests/variables.sh:
- Update regression tests to include ? and :? operators.
  • Loading branch information
McDutchie committed Sep 13, 2020
1 parent ab5dedd commit 9f2066f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 24 deletions.
22 changes: 2 additions & 20 deletions src/cmd/ksh93/sh/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -998,31 +998,13 @@ int sh_lex(Lex_t* lp)
mode = ST_NESTED;
continue;
case S_MOD1:
if(oldmode(lp)==ST_QUOTE || oldmode(lp)==ST_NONE)
{
/* allow ' inside "${...}" */
if(c==':' && fcgetc(n)>0)
{
n = state[n];
fcseek(-LEN);
}
if(n==S_MOD1)
{
mode = ST_QUOTE;
continue;
}
}
/* FALL THRU */
mode = ST_QUOTE;
continue;
case S_MOD2:
#if SHOPT_KIA
if(lp->kiafile)
refvar(lp,1);
#endif /* SHOPT_KIA */
if(c == ':' || c == '-' || c == '+' || c == '=')
{
mode = ST_QUOTE;
continue;
}
if(c!=':' && fcgetc(n)>0)
{
if(n!=c)
Expand Down
3 changes: 1 addition & 2 deletions src/cmd/ksh93/sh/macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,7 @@ static int varsub(Mac_t *mp)
}
else
{
int state = (!newops && mp->quote || c=='-' || c=='+' || c=='=') ? ST_QUOTE : ST_NESTED;
sh_lexskip(lp, RBRACE, 0, state);
sh_lexskip(lp, RBRACE, 0, sh_lexstates[ST_BRACE][c]==S_MOD1 ? ST_QUOTE : ST_NESTED);
stkseek(stkp,offset);
}
argp=stkptr(stkp,offset);
Expand Down
14 changes: 12 additions & 2 deletions src/cmd/ksh93/tests/variables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ wait
[[ $$ == ${.sh.pid} ]] || err_exit "\${.sh.pid} and \$$ differ in the parent shell (expected $$, got ${.sh.pid})"

# ======
# Parentheses after the '-', '+', and '=' expansion operators were causing syntax errors.
# Parentheses after the '-', '+', '=', and '?' expansion operators were causing syntax errors.
# Check both the unset variable case and the set variable case for each set of symbols.

unset -v foo
Expand All @@ -1058,7 +1058,7 @@ do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
done

foo=some_value
for op in - :- = :=
for op in - :- = := \? :\?
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
if [[ $exp != "$foo" ]]
Expand All @@ -1077,5 +1077,15 @@ do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
done
done

unset -v foo
for op in \? :\?
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
if [[ $exp != *": foo: $word" ]]
then err_exit "\${foo${op}${word}} when foo is not set: expected *\": foo: $word\", got \"$exp\""
fi
done
done

# ======
exit $((Errors<125?Errors:125))

0 comments on commit 9f2066f

Please sign in to comment.