bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

indirect variable behavior breakage


From: christopher barry
Subject: indirect variable behavior breakage
Date: Tue, 6 Mar 2018 23:38:05 -0500

From: cbarry@rajant.com
To: bug-bash@gnu.org
Subject: indirect variable behavior breakage

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu'
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE
-DRECYCLES_PIDS -DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin'  -O2 -g
-pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-fexceptions -fstack-protector-strong --param=ssp-buffer-size=4
-grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-m64 -mtune=generic uname output: Linux crucible.rajant.com
4.13.16-100.fc25.x86_64 #1 SMP Mon Nov 27 19:52:46 UTC 2017 x86_64
x86_64 x86_64 GNU/Linux Machine Type: x86_64-redhat-linux-gnu

Bash Version: 4.3 (works)
Patch Level: 43

#

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu'
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE
-DRECYCLES_PIDS -DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin'  -O2 -g
-pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-fexceptions -fstack-protector-strong --param=ssp-buffer-size=4
-grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-m64 -mtune=generic -Wno-parentheses -Wno-format-security uname output:
Linux 807847456c29 4.15.3-300.fc27.x86_64 #1 SMP Tue Feb 13 17:02:01
UTC 2018 x86_64 x86_64 x86_64 GNU/Linux Machine Type:
x86_64-redhat-linux-gnu

Bash Version: 4.4 (does not work)
Patch Level: 12
Release Status: release


Description:

a simple function that is used to test if a var is indirect or not and
return the value whether indirect or simply a string is no longer
working as expected on newer versions of bash.

Repeat-By:

This function works fine on this version (4.3.43) of bash (and
all previous versions I have access to, e.g. 4.2.46). It is broken, that
I am aware of, in 4.4.12 and 4.4.19, and possibly other versions as
well.

 function ivar() { echo -n "${!1:-${1}}"; }

This will take in a word as $1, and if it is a ref, will echo the
value of ref, but if it is not, will simply echo $1. This function
cares not about the string handed in, it rejects the indirection
silently, and IMHO correctly, regardless of the characters in that
string. I have found this function to be incredibly handy, and it's in
extensive use. It's simplicity and usefulness are very much relied upon.

Now, if the string starts with a number, or has a dash (possibly other
chars as well), it throws a syntax error. It's not clear to me why it
now feels the need to do this.

Usage:

# in a working bash version:

$ ping=pong
$ ivar "${ping}"
pong <-result

$ ivar 1.0.0
1.0.0 <-result

$ ivar m-4
m-4 <-result

$ declare -A myhash=(
[foo]=bar
[bar]=baz
[baz]=foo
)
$ ivar "myhash[@]"
baz foo bar <-result

$ ivar "myhash[foo]"
bar <-result


# in a newer, non-working bash version:

$ ivar 1.0.0
bash: 1.0.0: bad substitution <-result

$ ivar m-4
bash: m-4: bad substitution <-result


Fix:

The fix is to please restore the previous behavior.

I'm assuming it's that no one noticed this use-case breakage, or they
would not have made the change.

I think what's happened is before, bash looked into it's environment to
see if the string matched an already defined variable, and if it did,
it returned the value of the match. I think a change was introduced
that says, hey I'm going to see if this is a validly formatted variable
name first, and if not throw an error. The prior way also did that, but
it did it when the actual variable was set, not when it was being
looked up. Obviously, it won't find a match if the name is invalid, so
this may have been seen as an optimization. But in this case, it would
simply be better to return nothing and do nothing, not throw an error.
The name does not NEED to be valid here.

Anyway, that my guess :)

Thanks for looking into it,

Regards,
Christopher Barry
Rajant




reply via email to

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