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 
 http://gnu.org/licenses/gpl.html
 | 
 | 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 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: 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 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 1times.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 1times.txt`'
./b.bash:7+ (( ++ar[`echo -n 1times.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 1times.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




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


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 http://gnu.org/licenses/gpl.html
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:
http://www.gnu.org/software/gdb/bugs/.
(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 1times.txt`'
+ (( ++ar[`echo -n 1times.txt`] ))
++ echo -n 1
poc: line 4: ar: bad array subscript
++ echo -n 1
poc: line 4: ar[`echo -n 1times.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 dual...@gmail.com
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 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 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.