Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Eduardo A . Bustamante López
> On 2/18/15 3:49 PM, Maarten Billemont wrote:
[...]
> > I think the more important question isn't "why does (( behave this way?",
> > but rather "should (( behave this way?".
> > 
> > It's probably not reasonable to expect the author to know and take into
> > account that (( arr[$key] )) treats key's data as bash code. 

I guess this is part of the discussion here:
* http://lists.gnu.org/archive/html/bug-bash/2014-12/msg00071.html

The whole thread is very interesting.



Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Dan Douglas
it occurs when an associative array with an empty subscript is modified.

$ ( typeset -A a; x='a[$()]++'; ((x)); )
-bash: a: bad array subscript
-bash: a[$()]: bad array subscript
Segmentation fault (core dumped)

I could live without the error on an empty key to begin with. It can
be hard to protect against errors. Although bash doesn't throw
exceptions on referencing any undefined index like many languages, you
still have to guard against an empty key whenever its value isn't
known.

"${key+${a[$key]}}", or else "${a[${key}_]}" followed by
"${a[${key%_}]}" on each usage. Or at minimum [[ $key ]] on every
iteration of a loop over "${!a[@]}". It's almost uglier than `set -u'
workarounds...

-- 
Dan Douglas



Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Eduardo A . Bustamante López
On Wed, Feb 18, 2015 at 10:14:10PM +0100, emanuelczi...@cryptolab.net wrote:
> That segfault though:

I confirm that the segmentation fault is in the latest devel version.

dualbus@dualbus ~ % gdb
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
.
(gdb) file /tmp/bash-devel
Reading symbols from /tmp/bash-devel...done.
(gdb) r poc
Starting program: /tmp/bash-devel poc
+ declare -A ar
+ key='`echo -n "1">>times.txt`'
+ (( ++ar[`echo -n "1">>times.txt`] ))
++ echo -n 1
poc: line 4: ar: bad array subscript
++ echo -n 1
poc: line 4: ar[`echo -n "1">>times.txt`]: bad array subscript

Program received signal SIGSEGV, Segmentation fault.
bind_int_variable (lhs=0x7b8f08 "ar[`echo -n \"1\">>times.txt`]", rhs=0x7b32f8 
"1") at variables.c:2878
warning: Source file is more recent than executable.
2878
(gdb) bt
#0  bind_int_variable (lhs=0x7b8f08 "ar[`echo -n \"1\">>times.txt`]", 
rhs=0x7b32f8 "1") at variables.c:2878
#1  0x0044e901 in expr_bind_variable (lhs=0x7b8f08 "ar[`echo -n 
\"1\">>times.txt`]", rhs=0x7b32f8 "1") at expr.c:317
#2  0x0044f984 in exp0 () at expr.c:987
#3  0x0044f89f in exp1 () at expr.c:955
#4  0x0044f790 in exppower () at expr.c:910
#5  0x0044f58a in exp2 () at expr.c:835
#6  0x0044f51f in exp3 () at expr.c:809
#7  0x0044f4b0 in expshift () at expr.c:785
#8  0x0044f403 in exp4 () at expr.c:755
#9  0x0044f38c in exp5 () at expr.c:733
#10 0x0044f34a in expband () at expr.c:715
#11 0x0044f30c in expbxor () at expr.c:696
#12 0x0044f2ce in expbor () at expr.c:677
#13 0x0044f23f in expland () at expr.c:650
#14 0x0044f1ac in explor () at expr.c:622
#15 0x0044f075 in expcond () at expr.c:578
#16 0x0044ed3c in expassign () at expr.c:466
#17 0x0044ed07 in expcomma () at expr.c:446
#18 0x0044ec84 in subexpr (expr=0x7b9d88 "++ar[`echo -n 
\"1\">>times.txt`]") at expr.c:428
#19 0x0044eb1c in evalexp (expr=0x7b9d88 "++ar[`echo -n 
\"1\">>times.txt`]", validp=0x7fffdd6c) at expr.c:393
#20 0x004403c4 in execute_arith_command (arith_command=0x7b9a48) at 
execute_cmd.c:3561
#21 0x0043bc18 in execute_command_internal (command=0x7b8d88, 
asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x7b8e68) at 
execute_cmd.c:995
#22 0x0043add0 in execute_command (command=0x7b8d88) at 
execute_cmd.c:416
#23 0x004263dd in reader_loop () at eval.c:163
#24 0x0042412b in main (argc=2, argv=0x7fffdfe8, 
env=0x7fffe000) at shell.c:757
(gdb) info locals
v = 0x0
isint = 0
isarr = 1
implicitarray = 0
(gdb) l
2873  else
2874INVALIDATE_EXPORTSTR (entry);
2875
2876  if (var_isset (entry))
2877dispose_command (function_cell (entry));
2878
2879  if (value)
2880var_setfunc (entry, copy_command (value));
2881  else
2882var_setfunc (entry, 0);


This patch seems to fix it:

dualbus@dualbus ~/local/src/bash
 % git log -p -1|cat
commit 5d29a37a60c9daabf85de66dd7df3c459bd0c468
Author: Eduardo A. Bustamante López 
Date:   Wed Feb 18 18:53:04 2015 -0600

Check if v is not NUL

diff --git a/variables.c b/variables.c
index 2f07ebb..91912cd 100644
--- a/variables.c
+++ b/variables.c
@@ -2875,6 +2875,7 @@ bind_int_variable (lhs, rhs)
   if (v && isint)
 VSETATTR (v, att_integer);

+  if (v)
   VUNSETATTR (v, att_invisible);

   return (v);



Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread emanuelczirai

tl;dr: thanks! no reply needed;

Thanks guys. I had a hard time accepting that this is how it's supposed 
to work.

I accepted it now. :)
I just hope nobody is going to try to exploit it or something.

That segfault though:
set -x
declare -A ar
key='`echo -n "1">>times.txt`'
((++ar[$key])) # cmd in $key gets executed twice too
declare -p ar

$ ./b.bash
./b.bash:5+ declare -A ar
./b.bash:6+ key='`echo -n "1">>times.txt`'
./b.bash:7+ (( ++ar[`echo -n "1">>times.txt`] ))
../b.bash:7+ echo -n 1
./b.bash: line 7: ar: bad array subscript
../b.bash:7+ echo -n 1
./b.bash: line 7: ar[`echo -n "1">>times.txt`]: bad array subscript
Segmentation fault (core dumped)

Disclaimer: I have stumbled upon this "non-issue" by mistake and I've no 
intention of exploiting anything ('cause I got principles, heh; 
seriously though)

Ok bye.

PS: this still makes me sad though :')

On 2015-02-18 20:14, Chet Ramey wrote:

On 2/16/15 12:23 PM, emanuelczi...@cryptolab.net wrote:

Oh I see, I had no idea that's how it's meant to work. My apologies.

However this case still doesn't work, but maybe I should use single 
quotes

all the time?:

this fails(double quotes):
$ declare -A ar
$ idbad2="["
$ let "ar[$idbad2]+=11"
bash: let: ar[[]+=11: bad array subscript (error token is "ar[[]+=11")
$ declare -p ar
bash: declare: ar: not found


Bash expects the brackets to match.  This is true when the parser tries 
to

find the closing bracket and when the arithmetic expression evaluator
does -- they use the same criteria.  You can make a case that they 
should
not have to match, but bash has always behaved this way and you'll have 
to

work with it, at least for now.


this works(single quotes):
$ let 'ar[$idbad2]+=11'
$ declare -p ar
declare -A ar='(["["]="11" )'


This works because the arithmetic expression evaluator doesn't have to
deal with the extra `[' when trying to find the end of the subscript, 
and

it's smart enough to figure out whether it's dealing with an indexed or
associative array and evaluate accordingly.


also this variant does the same:


Because (( and let are essentially equivalent.

Chet




Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Chet Ramey
On 2/18/15 3:49 PM, Maarten Billemont wrote:
> > also this variant does the same:
> > $ (('ar[$idbad2]+=11')) 
> 
> 
> Because (( and let are essentially equivalent.
> 
> 
> I think the more important question isn't "why does (( behave this way?",
> but rather "should (( behave this way?".
> 
> It's probably not reasonable to expect the author to know and take into
> account that (( arr[$key] )) treats key's data as bash code. 

What does `bash code' mean?  It undergoes the usual set of word expansions.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Maarten Billemont
>
> > also this variant does the same:
> > $ (('ar[$idbad2]+=11'))


> Because (( and let are essentially equivalent.


I think the more important question isn't "why does (( behave this way?",
but rather "should (( behave this way?".

It's probably not reasonable to expect the author to know and take into
account that (( arr[$key] )) treats key's data as bash code.  Really, the
behaviour of ((' arr[$key] ')) makes more sense as a default behaviour.
The former is broken (as the expectation that $key expands data is not met).


Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-18 Thread Eduardo A . Bustamante López
On Wed, Feb 18, 2015 at 08:30:31PM +0100, SN wrote:
> > Also, remember to state the version you're using.
> I pasted version in the format printed by bashbug. In case it's not enough:
Yep, you omitted this part though:
Bash Version: 4.3 <- that
Patch Level: 33
Release Status: release

Let's wait to see what Chet has to say on that matter. Changes on the devel
branch are not documented, so he's the only one that knows what's going on.



Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-18 Thread SN
> Also, remember to state the version you're using.
I pasted version in the format printed by bashbug. In case it's not enough:

$ LANG=C bash --version
GNU bash, version 4.3.33(1)-release (x86_64-pc-linux-gnu)
...

> This particular
> feature seems to behave differently in the -devel branch:
>
>
> | $ cat declare.bash
> | #!/bin/bash
> | 
> | for bash in /tmp/bash-* /bin/bash; do
> |   "$bash" --version
> |   printf '%s\n' ---
> |   "$bash" -c 'declare -a a; declare -p a'
> |   "$bash" -c 'declare -a a=(); declare -p a'
> |   "$bash" -c 'declare -a a="()"; declare -p a'
> |   "$bash" -c 'f(){ declare -a a; declare -p a; }; f'
> |   "$bash" -c 'f(){ declare -a a=(); declare -p a; }; f'
> |   "$bash" -c 'f(){ declare -a a="()"; declare -p a; }; f'
> |   printf '%s\n' ---
> | done
> | 
> | $ ./declare.bash
> | GNU bash, version 4.4.0(1)-devel (x86_64-unknown-linux-gnu)
> | Copyright (C) 2014 Free Software Foundation, Inc.
> | License GPLv3+: GNU GPL version 3 or later 
> 
> | 
> | This is free software; you are free to change and redistribute it.
> | There is NO WARRANTY, to the extent permitted by law.
> | ---
> | declare -a a
> | declare -a a=()
> | declare -a a=()
> | declare -a a
> | declare -a a=()
> | declare -a a=([0]="()")
There is an inconsistency in how the declare a="()" is interpreted here,
as you notice below.

However, the main issue in 4.3.33 from the report is that declare -p
does not produce "reusable" output.
This simple test case will show what I mean:

$ f() { declare -a a="()"; eval "declare -p a"; }; f
bash: declare: a: not found

compare with this:

$ f() { declare -a a=(); eval "declare -p a"; }; f
declare -a a='()'

or

$ f() { local a="foo"; eval "declare -p a"; }; f
declare -- a="foo"

(See also:
https://lists.gnu.org/archive/html/bug-bash/2011-12/msg00067.html.)

Thanks for checking it on various versions! In 4.4.0(1)-devel this test
passes for a few variations I tried. For example:

$ f() { declare -a a="()"; eval "declare -p a"; printf "[%s]\n"
"${a[@]}"; }; f
declare -a a=([0]="()")
[()]

and

$ f() { declare -a a=(); eval "declare -p a"; printf "[%s]\n" "${a[@]}";
}; f
declare -a a=()
[]

so it's good.

> You're reporting the behavior of the master branch, but it seems to
> be already fixed in devel. I'm not sure about the inconsistency
> between:
> |   "$bash" -c 'declare -a a="()"; declare -p a'
> and
> |   "$bash" -c 'f(){ declare -a a="()"; declare -p a; }; f'
>
> IMO these two should have the same behaviour.
I guess so.
> Chet will be able to
> clarify this.




Re: array subscripts act differently for integers(ie. let)

2015-02-18 Thread Chet Ramey
On 2/16/15 12:23 PM, emanuelczi...@cryptolab.net wrote:
> Oh I see, I had no idea that's how it's meant to work. My apologies.
> 
> However this case still doesn't work, but maybe I should use single quotes
> all the time?:
> 
> this fails(double quotes):
> $ declare -A ar
> $ idbad2="["
> $ let "ar[$idbad2]+=11"
> bash: let: ar[[]+=11: bad array subscript (error token is "ar[[]+=11")
> $ declare -p ar
> bash: declare: ar: not found

Bash expects the brackets to match.  This is true when the parser tries to
find the closing bracket and when the arithmetic expression evaluator
does -- they use the same criteria.  You can make a case that they should
not have to match, but bash has always behaved this way and you'll have to
work with it, at least for now.

> this works(single quotes):
> $ let 'ar[$idbad2]+=11'
> $ declare -p ar
> declare -A ar='(["["]="11" )'

This works because the arithmetic expression evaluator doesn't have to
deal with the extra `[' when trying to find the end of the subscript, and
it's smart enough to figure out whether it's dealing with an indexed or
associative array and evaluate accordingly.

> also this variant does the same:

Because (( and let are essentially equivalent.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Trap does not work if a subshell wait(s) for job

2015-02-18 Thread Dr. Werner Fink
Hi,

found due to a hang in the test suite of gnutls, after debugging I've
extract the example code

 launch_server () { sleep 100 & l=$!; trap "kill -15 $l" 15; echo $l; wait 
$l; }
 launch_server & x=$!
 sleep 2
 kill $x

which does wait the full 100 seconds with bash 4.3 but with the old bash 4.2 
only 2 seconds.

Werner

-- 
  "Having a smoking section in a restaurant is like having
  a peeing section in a swimming pool." -- Edward Burr


signature.asc
Description: Digital signature