ash: remove arithmetic expansion collapsing at parse time

Collapsing arithmetic expansion is incorrect when the inner arithmetic
expansion is a part of a parameter expansion.

Test case:
   unset a
   echo $((3 + ${a:=$((4 + 5))}))
   echo $a
Old result:
   12
   (4 + 5)
New result:
   12
   9

Based on commit bb777a6 from git://git.kernel.org/pub/scm/utils/dash/dash.git
by Herbert Xu

function                                             old     new   delta
readtoken1                                          3180    3163     -17

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2015-05-18 09:56:16 +02:00 committed by Denys Vlasenko
parent 7e4ed267b6
commit ad88bdee0c
3 changed files with 11 additions and 12 deletions

View File

@ -11316,9 +11316,9 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
parenlevel--; parenlevel--;
} else { } else {
if (pgetc() == ')') { if (pgetc() == ')') {
c = CTLENDARI;
if (--arinest == 0) { if (--arinest == 0) {
syntax = prevsyntax; syntax = prevsyntax;
c = CTLENDARI;
} }
} else { } else {
/* /*
@ -11809,18 +11809,12 @@ parsearith: {
if (++arinest == 1) { if (++arinest == 1) {
prevsyntax = syntax; prevsyntax = syntax;
syntax = ARISYNTAX; syntax = ARISYNTAX;
USTPUTC(CTLARI, out);
if (dblquote)
USTPUTC('"', out);
else
USTPUTC(' ', out);
} else {
/*
* we collapse embedded arithmetic expansion to
* parenthesis, which should be equivalent
*/
USTPUTC('(', out);
} }
USTPUTC(CTLARI, out);
if (dblquote)
USTPUTC('"', out);
else
USTPUTC(' ', out);
goto parsearith_return; goto parsearith_return;
} }
#endif #endif

View File

@ -0,0 +1,3 @@
unset a
echo $((3 + ${a:=$((4 + 5))}))
echo $a