[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
In ((0? var: 0)), expressions stored in var are evaluated.
From: |
Koichi MURASE |
Subject: |
In ((0? var: 0)), expressions stored in var are evaluated. |
Date: |
Mon, 7 Nov 2016 11:39:22 +0900 |
Hello, here is another bashbug report.
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu'
-DCONF_VENDOR='pc'
-DLOCALEDIR='/home/murase/opt/bash-4.4/share/locale' -DPACKAGE='ba\
sh' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -O2
-march=native -Wno-parentheses -Wno-format-security
uname output: Linux padparadscha 4.7.2-101.fc23.i686 #1 SMP Fri Aug 26
16:39:46 UTC 2016 i686 i686 i386 GNU/Linux
Machine Type: i686-pc-linux-gnu
Bash Version: 4.4
Patch Level: 0
Release Status: release
Description:
Variables in the discarded branches of conditional expressions are
evaluated. This is caused by the function `evalcond' in expr.c. The
calls of `readtok' in `evalcond' are made before the global variable
`noeval' is set up.
Repeat-By:
$ bash-4.4 -c 'a=0 x="a=1"; ((0?x:0)); echo $a'
1
$ bash-4.4 -c 'a=0 x="a=1"; ((1?0:x)); echo $a'
1
The value 1 is set by the evaluation of x. But I expect the result 0
because the variable `x' is in the discarded branch and therefore is
natural not to be evaluated. All the other similar patterns returns 0:
$ bash-4.4 -c 'a=0 x="a=1"; ((0?(x):0)); echo $a'
0
$ bash-4.4 -c 'a=0 x="a=1"; ((0?$x:0)); echo $a'
0
In addition, variables in logical and/or expressions are not
evaluated if the branch is not selected:
$ bash-4.4 -c 'a=0 x="a=1"; ((0&&x)); echo $a'
0
$ bash-4.4 -c 'a=0 x="a=1"; ((1||x)); echo $a'
0
There is another pattern caused by the same bug.
$ bash-4.4 -c 'a=0; ((0?arr[a=1]:0)); echo $a'
1
All the versions of bash from 3.0 to 4.4 behave the same. Is the
result `1' intended? It's not intuitive for me.
Fix:
In `evalcond', the selection of branches are controlled by setting
the global variable `noeval'. While, evaluation of variables are made
in `readtok'. The function `readtok' is aware of `noeval', but is
called by `evalcond' before `noeval' is modified. In the following
patch, the calls of `readtok' are moved after the set of `noeval'.
diff --git a/expr.c b/expr.c
index 1ddb693..ad3e24d 100644
--- a/expr.c
+++ b/expr.c
@@ -578,24 +578,21 @@ expcond ()
rval = cval = explor ();
if (curtok == QUES) /* found conditional expr */
{
- readtok ();
- if (curtok == 0 || curtok == COL)
- evalerror (_("expression expected"));
if (cval == 0)
{
set_noeval = 1;
noeval++;
}
+ readtok ();
+ if (curtok == 0 || curtok == COL)
+ evalerror (_("expression expected"));
val1 = EXP_HIGHEST ();
if (set_noeval)
noeval--;
if (curtok != COL)
evalerror (_("`:' expected for conditional expression"));
- readtok ();
- if (curtok == 0)
- evalerror (_("expression expected"));
set_noeval = 0;
if (cval)
{
@@ -603,7 +600,11 @@ expcond ()
noeval++;
}
+ readtok ();
+ if (curtok == 0)
+ evalerror (_("expression expected"));
val2 = expcond ();
+
if (set_noeval)
noeval--;
rval = cval ? val1 : val2;
Regards,
Koichi
- In ((0? var: 0)), expressions stored in var are evaluated.,
Koichi MURASE <=