bug-bash
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]