On Wed, Apr 27, 2016 at 08:58:47PM +0200, Piotr Grzybowski wrote: > On 27 Apr 2016, at 20:43, Eduardo A. Bustamante López wrote: > > > The attached patch seems to take care of at least these two cases: [..] > > your patch also adresses the original Grisha's report: > > declare -r T=5; ref=$T; declare -n ref; ref=10; declare -n T; > > cheers, > pg > >
Actually, this seems to be a special case, just because '5' is an invalid variable name. But the problem still exists: | dualbus@hp ...src/gnu/bash % ./bash -c 'declare -r RO=x; r=$RO; declare -n r; x=y; declare -n RO; RO=z; declare -p RO; echo "$RO"' | declare -nr RO="x" | z The problem here is that it shouldn't be possible to set the nameref attribute on a variable that already has the readonly attribute set. The RO variable is still readonly, but you can modify the value it expands to, by doing that trick. I compiled the following list of test cases: | r=/; declare -n r | declare -n r=/ | declare -n r; r=/ | declare -n r; for r in /; do :; done | declare -n r; select r in 1; do :; done <<< / | declare -n r; ((r=0)) | ((r=0)); declare -n r | r=/ declare -n r | f() { declare -n r; }; r=/ f | f() { echo $r; }; declare -n r; r=/ f | declare -n r; : ${r:=/} | declare -n r; exec {r}>/dev/null | declare -n r; coproc r { :; }; echo $r | declare -r RO=x; r=$RO; declare -n r; x=y; declare -n RO; RO=z; declare -p RO; echo "$RO" And my patch seems to address just a few: | dualbus@hp ...src/gnu/bash % while read -r case; do echo "case: $case"; ./bash -c "$case"; done <../cases | case: r=/; declare -n r | ./bash: line 0: declare: /: invalid variable name for name reference | case: declare -n r=/ | ./bash: line 0: declare: /: invalid variable name for name reference | case: declare -n r; r=/ | ./bash: `/': not a valid identifier | case: declare -n r; for r in /; do :; done | ./bash: `/': not a valid identifier | case: declare -n r; select r in 1; do :; done <<< / | 1) 1 | #? ./bash: `': not a valid identifier | case: declare -n r; ((r=0)) | ./bash: `0': not a valid identifier | case: ((r=0)); declare -n r | ./bash: line 0: declare: 0: invalid variable name for name reference | case: r=/ declare -n r | ./bash: line 0: declare: /: invalid variable name for name reference | case: f() { declare -n r; }; r=/ f | environment: line 0: declare: /: invalid variable name for name reference | case: f() { echo $r; }; declare -n r; r=/ f | / | case: declare -n r; : ${r:=/} | ./bash: `/': not a valid identifier | case: declare -n r; exec {r}>/dev/null | ./bash: `10': not a valid identifier | case: declare -n r; coproc r { :; }; echo $r | 63 | case: declare -r RO=x; r=$RO; declare -n r; x=y; declare -n RO; RO=z; declare -p RO; echo "$RO" | declare -nr RO="x" | z The select case seems to be wrong, but I'm too lazy to figure out how to write it properly. I think the coproc case was recently reported too. I'm not sure about the tempenv variable. -- Eduardo Bustamante https://dualbus.me/