Re: param expansion with single-character special vars in the environment

2016-05-31 Thread Chet Ramey
On 5/27/16 1:38 PM, Grisha Levit wrote:

> How about removing the nameref attribute from an existing readonly
> variable?  This is currently allowed but perhaps for completeness it should
> be forbidden?

For ksh93 compatibility, bash should prevent the readonly attribute from
being removed from readonly nameref variables that have a value.  namerefs
that only have attributes (technically unset) can be manipulated like that.
FWIW, ksh93 prohibits namerefs with values from being set to readonly.

-- 
``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: param expansion with single-character special vars in the environment

2016-05-27 Thread Grisha Levit
On Mon, May 2, 2016 at 11:55 AM, Chet Ramey  wrote:

> I agree; `declare' should not allow attempts to add the nameref attribute
> to an existing readonly variable.


How about removing the nameref attribute from an existing readonly
variable?  This is currently allowed but perhaps for completeness it should
be forbidden?


Re: param expansion with single-character special vars in the environment

2016-05-16 Thread Chet Ramey
On 5/14/16 12:16 PM, Grisha Levit wrote:
> One more case, which currently segfaults:
> 
> |declare -n REPLY; read <<< / |
> 
> easy fix:

Thanks for the fix.

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/



Re: param expansion with single-character special vars in the environment

2016-05-16 Thread Chet Ramey
On 5/14/16 12:41 PM, Grisha Levit wrote:
> On Mon, May 2, 2016 at 2:30 PM, Chet Ramey  > wrote:
> 
> I ended up writing a new function: valid_nameref_value(name, flags) which
> I can customize to serve this purpose.
> 
> Looks like this ends up getting bypassed in some cases when the value is an
> empty string:

Yes, it was.  That was intended to solve a specific problem, so I solved
it in a different way.  Thanks for the additional test cases.

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/



Re: param expansion with single-character special vars in the environment

2016-05-14 Thread Grisha Levit
One more case, which currently segfaults:

declare -n REPLY; read <<< /

easy fix:

diff --git a/builtins/read.def b/builtins/read.def
index 5e2348c..8f6bd2b 100644--- a/builtins/read.def+++ b/builtins/read.def
@@ -797,9 +797,11 @@ assign_vars:
}
   else
var = bind_variable ("REPLY", input_string, 0);-
VUNSETATTR (var, att_invisible);-  if (readonly_p (var) ||
noassign_p (var))++  if (var == 0 || readonly_p (var) ||
noassign_p (var))
retval = EXECUTION_FAILURE;+  else+VUNSETATTR
(var, att_invisible);

   xfree (input_string);
   return (retval);

​

On Fri, May 6, 2016 at 11:39 AM, Chet Ramey  wrote:

> On 4/27/16 4:07 PM, Eduardo A. Bustamante López wrote:
> > Here's the updated list of cases:
>
> Thanks for the list of test cases; these were very helpful.
>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRUc...@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>


Re: param expansion with single-character special vars in the environment

2016-05-06 Thread Chet Ramey
On 4/27/16 4:07 PM, Eduardo A. Bustamante López wrote:
> Here's the updated list of cases:

Thanks for the list of test cases; these were very helpful.

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/



Re: param expansion with single-character special vars in the environment

2016-05-05 Thread Chet Ramey
On 5/4/16 3:37 PM, Piotr Grzybowski wrote:
> 
> On 4 May 2016, at 17:51, Chet Ramey wrote:
> 
>> The issue I'm thinking about currently is whether or not to allow nameref
>> variables to have numeric (integer) values.  bash-4.3 didn't allow those
>> values to be expanded, but allowed them to be assigned.  It doesn't seem
>> harmful to change the error to assignment time.
> 
> I vote for error at assignment, whats the point of allowing pointless 
> assignment?

No reason, except for minimal backwards compatibility.  I'm leaning towards
that position myself.


-- 
``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: param expansion with single-character special vars in the environment

2016-05-04 Thread Dan Douglas
...Also remember it isn't feasible to actually validate a "name" in a
script because a name can contain a subscript with a command
substitution that effectively requires parsing the full language.
(there are some tricks like with `set -nv` and reading its output to
shanghai the shell parser into doing your bidding, but that's not very
practical.). Before bash had namerefs, it could ignore aspects of
"invalid" names, like trailing characters after an array subscript,
which makes some valid ksh names at least get partially interpreted in
bash, like `a[foo].bar` or `a[foo][bar]`.



Re: param expansion with single-character special vars in the environment

2016-05-04 Thread Dan Douglas
On Wed, May 4, 2016 at 2:37 PM, Piotr Grzybowski  wrote:
>
> On 4 May 2016, at 17:51, Chet Ramey wrote:
>
>> The issue I'm thinking about currently is whether or not to allow nameref
>> variables to have numeric (integer) values.  bash-4.3 didn't allow those
>> values to be expanded, but allowed them to be assigned.  It doesn't seem
>> harmful to change the error to assignment time.
>
> I vote for error at assignment, whats the point of allowing pointless 
> assignment?

Since almost all bash errors are runtime errors that you might never
hit until something you didn't expect gets passed the wrong value,
errors (especially fatal errors) that might sound like a good idea at
first end up being totally pathological. You end up having to manually
test and validate all inputs to all functions whose callers aren't
strictly controlled, or add redirects to hide warning messages for
non-fatal errors. There are even cases where it's useful to allow or
at least ignore invalid names. If this were a language where I could
get a compiler error caught through static analysis then it would be a
different story.



Re: param expansion with single-character special vars in the environment

2016-05-04 Thread Piotr Grzybowski

On 4 May 2016, at 17:51, Chet Ramey wrote:

> The issue I'm thinking about currently is whether or not to allow nameref
> variables to have numeric (integer) values.  bash-4.3 didn't allow those
> values to be expanded, but allowed them to be assigned.  It doesn't seem
> harmful to change the error to assignment time.

I vote for error at assignment, whats the point of allowing pointless 
assignment?

pg





Re: param expansion with single-character special vars in the environment

2016-05-03 Thread Chet Ramey
On 4/28/16 5:20 PM, Grisha Levit wrote:
> 
> On Thu, Apr 28, 2016 at 3:14 PM, Piotr Grzybowski  > wrote:
> 
>  b. we can forbid
># declare -n T
>when T is a readonly variable
> 
> 
> This is the one that makes the most sense to me.  It shouldn't however be
> forbidden to do `declare -nr RO=foo' if RO is not already a readonly variable.

Interesting that ksh93 throws a usage error when presented with that (using
typeset, of course).

-- 
``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: param expansion with single-character special vars in the environment

2016-05-02 Thread Dan Douglas
On Mon, May 2, 2016 at 1:59 PM, Grisha Levit  wrote:
>
> On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  wrote:
>>
>> and this one throws away the nameref attribute:
>>
>> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
>
>
> I think it's important to note that the nameref attribute is thrown away at
> the `typeset -i foo' step, which makes some sense since `typeset -n -i' does
> not seem to be valid in ksh.

ksh93 stores integer variables as actual integers internally so
there's no opportunity for storing the expression, and the nameref
attribute just wouldn't make sense.

Bash stores a string that gets coerced as necessary when performing
arithmetic. That's why ksh is so much faster than bash when you
declare integers, and an integer will wrap around while a string will
get converted back and fourth via pretty much the same rules bash
uses.

 ~ $ ksh -c 'integer n=$(getconf LONG_MAX); typeset m=$n; ((m++,n++));
typeset -p n m'
typeset -l -i n=-9223372036854775808
m=9.22337203685477581e+18

The only effect of -i in bash is to modify the way += assignments work.



Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 5/2/16 2:59 PM, Grisha Levit wrote:
> 
> On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  > wrote:
> 
> and this one throws away the nameref attribute:
> 
> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
> 
> 
> I think it's important to note that the nameref attribute is thrown away at
> the `typeset -i foo' step, which makes some sense since `typeset -n -i'
> does not seem to be valid in ksh.

Yes.  It's just that it's undocumented and done without a warning.


-- 
``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: param expansion with single-character special vars in the environment

2016-05-02 Thread Grisha Levit
On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  wrote:

> and this one throws away the nameref attribute:
>
> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
>

I think it's important to note that the nameref attribute is thrown away at
the `typeset -i foo' step, which makes some sense since `typeset -n -i'
does not seem to be valid in ksh.


Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 8:36 PM, Grisha Levit wrote:
> 
> On Wed, Apr 27, 2016 at 6:47 PM, Piotr Grzybowski  > wrote:
> 
> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
> 
> 
> Shouldn't this (and the other patch) check valid_array_reference as well to
> support declare -n ref=a[x] ?

I ended up writing a new function: valid_nameref_value(name, flags) which
I can customize to serve this purpose.

-- 
``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: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 7:37 PM, Piotr Grzybowski wrote:
> 
>  sorry for the spam concerning the patch: it needs merging with what Eduardo 
> posted (excluding the `declare -n r; declare -n r;' regression bug), and what 
> is in #ifdef 0 in declare.def; I just found out that it is exactly what it 
> intends to do.
>  I am sure we need to forbid the illegal identifiers during declare -n and in 
> later assignments to the nameref variable.

Yes, among other things.


-- 
``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: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 4:07 PM, Eduardo A. Bustamante López wrote:

> The 'mapfile' one is interesting, because it drops the nameref attribute from
> the 'r' variable.

Array variables can't have the nameref attribute.  The process of creating
and clearing the array with the name supplied as an argument clears that
attribute.  Maybe it should display a warning.

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/



Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 8:41 AM, Grisha Levit wrote:
> On Wed, Apr 27, 2016 at 7:37 AM, Piotr Grzybowski  > wrote:
> 
>  It seems to me that creating the reference should be allowed, but the
> access to the referenced variable should honor its attributes.
> 
> Once you convert the variable to a reference, you can control its value by
> modifying the value of a different variable with the name that corresponds
> to the value of the readonly variable, so “access to the referenced
> variable should honor its attributes” probably won’t do much (If I
> understand your suggestion correctly).

I agree; `declare' should not allow attempts to add the nameref attribute
to an existing readonly variable.  I will make this change before bash-4.4
is released.

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/



Re: param expansion with single-character special vars in the environment

2016-05-01 Thread Chet Ramey
On 4/25/16 3:48 PM, Grisha Levit wrote:
> There seems to be a bug that if an array variable with a name matching one
> of the special single-character variables exists, then that variable is
> used during substring expansion and parameter transformation.
> 
> There is also a potential issue with namerefs, in that they allow
> creating/modifying variables with invalid identifiers if a variable is
> defined first and subsequently given the nameref attribute, which is how
> the above behavior can be uncovered.

Yes, clearly the set of names that is acceptable as a value to a nameref
variable needs to be constrained.  That set should include valid shell
identifiers, valid array references, and positional parameters (for
compatibility with ksh93).  Once you limit the set of names to omit the
problematic ones, bugs like the one above don't happen.

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/



Re: param expansion with single-character special vars in the environment

2016-04-28 Thread Grisha Levit
On Thu, Apr 28, 2016 at 3:14 PM, Piotr Grzybowski 
wrote:

>  b. we can forbid
># declare -n T
>when T is a readonly variable
>

This is the one that makes the most sense to me.  It shouldn't however be
forbidden to do `declare -nr RO=foo' if RO is not already a readonly
variable.

This feels similar to the restriction that forbids removing the readonly
attribute from a readonly variable.


Re: param expansion with single-character special vars in the environment

2016-04-28 Thread Piotr Grzybowski

 ok, after some thinking, this one seems certain:

1. forbid adding nameref when the value is not a valid identifier:
 # declare -n reference=/
 should be forbidden, as well as later assignments to nameref with strings 
being illegal identifiers, as we discussed/patched.


 what remains (rest of the reports by Grisha and others can be brought to this):

2. creating a reference that "masks" the readonly variable:
  # bash -c 'declare -r T=a; echo $T; declare -n ref=a T; ref=; echo $T; 
declare -p T;'
  a
  
  declare -nr T="a"

 a. we can patch to expand always to the readonly variable value:
   # echo $T
   would not follow references but first resolve to value of T, as expected by 
most
   and introduce another way to dereference at expansion for those who did 
create the namref
   on purpose.

 b. we can forbid
   # declare -n T
   when T is a readonly variable

 c. we can forbid the assignment: 
   # ref=

 d. try to detect the "nameref loop"

2.b-d seem illogical to me, and against the decision behind introducing the 
namerefs.

cheers,
pg



On 28 Apr 2016, at 02:36, Grisha Levit wrote:

> 
> On Wed, Apr 27, 2016 at 6:47 PM, Piotr Grzybowski  wrote:
> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
> 
> Shouldn't this (and the other patch) check valid_array_reference as well to 
> support declare -n ref=a[x] ?




Re: param expansion with single-character special vars in the environment

2016-04-28 Thread Piotr Grzybowski
On 28 Apr 2016, at 02:36, Grisha Levit wrote:

> 
> On Wed, Apr 27, 2016 at 6:47 PM, Piotr Grzybowski  wrote:
> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
> 
> Shouldn't this (and the other patch) check valid_array_reference as well to 
> support declare -n ref=a[x] ?

 yes most certainly should, and also should do a bit more.
 frankly, your original report:

readonly TMOUT=5; ref=$TMOUT; declare -n ref; ref=10; declare -n TMOUT; read

really scares me. The fix should also go to the nameref code, since I refuse to 
sanction the apparent entry in the variable table with name="5" and value="10" 
after this code is run, just by the fact that $TMOUT value is not a valid 
identifier.

cheers,
pg





Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Grisha Levit
On Wed, Apr 27, 2016 at 6:47 PM, Piotr Grzybowski 
wrote:

> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
>

Shouldn't this (and the other patch) check valid_array_reference as well to
support declare -n ref=a[x] ?


Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Piotr Grzybowski

 sorry for the spam concerning the patch: it needs merging with what Eduardo 
posted (excluding the `declare -n r; declare -n r;' regression bug), and what 
is in #ifdef 0 in declare.def; I just found out that it is exactly what it 
intends to do.
 I am sure we need to forbid the illegal identifiers during declare -n and in 
later assignments to the nameref variable.

cheers,
pg

On 28 Apr 2016, at 00:47, Piotr Grzybowski wrote:

> 
> a short summary:
> 
> 1. there is a real bug reported here: allowing namref on illegal identifiers, 
> if we assume that the value of the variable that has nameref attribute is the 
> name of the variable it refers to, then we have to require that declare -n 
> a=b anly allows legal identifiers for b:
> 
> diff --git a/builtins/declare.def b/builtins/declare.def
> index a1e9b4e..53b688c 100644
> --- a/builtins/declare.def
> +++ b/builtins/declare.def
> @@ -719,7 +719,7 @@ declare_internal (list, local_var)
>  if (onref)
>aflags |= ASS_NAMEREF;
>  v = bind_variable_value (var, value, aflags);
> - if (v == 0 && onref)
> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
>{
>  sh_invalidid (value);
>  assign_error++;
> 
> 2. the other matter that you, Grisha, reported, and Eduardo commented heavily 
> on, is not a matter of creating a nameref, but a matter of overriding 
> readonly variables identifiers, a matter of discussion if it should be 
> allowed (coproc bugs and getopt discussed lately being other examples). But 
> it is not a bug, the decision was made to allow namerefs, they work as 
> documented, the readonly variables are not touched, they identifiers are used 
> as per definition of nameref. A matter of discussion should be: how to 
> protect some variables, like the ones that were mentioned (PATH, TMOUT, etc). 
> If the readonly means also "do not give and attributes" then declare -n (and 
> others) should be forbidden on readonly variables. On the other hand we can 
> think of declaring variable as: `protected a' which would mean that no 
> modification of attributes is possible, but variable data can be changed, as 
> opposed to `readonly a' which could mean "data of the variable cannot be 
> changed" and finally both as, e.g.: `exclusive a' meaning readonly|protected.
> 
> 3. I have no idea about this global/local thing Grisha reported.
> 
> cheers,
> pg
> 
> 
> 
> On 25 Apr 2016, at 22:57, Grisha Levit wrote:
> 
>> A related issue is with adding the nameref attribute to a readonly variable. 
>> Not sure if that should be allowed, as it can be used to change the meaning 
>> of the variable, even for variables that bash is using internally:
>> 
>> $ TIMEFORMAT='%R'
>> 
>> $ time bash -c 
>> 'readonly TMOUT=5; read'
>> 5.007
>> 
>> $ time bash -c 
>> 'readonly TMOUT=5; ref=$TMOUT; declare -n ref; ref=10; declare -n TMOUT; 
>> read'
>> 10.004
>> The same technique works for circumventing PATH in a restricted shell:
>> 
>> $ PATH='/restricted/bin' $BASH -r -c 'type sed; ref=$PATH; declare -n ref; 
>> ref=/usr/bin; declare -n PATH; type sed'
>> bash
>> bash: line 
>> 0: type
>> : sed: not found
>> sed is /usr/bin/sed
>> 
> 




Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Piotr Grzybowski

 wait, this one is all right, look:

1. you are making a readonly variable: readonly USER=sandbox
2. then you are creating a nameref: declare -n USER; from now on the 
assignments to USER are assignments to variable of name sandbox
3. then you create a variable sandbox and assign a value

since sandbox variable is not read only, then assignments are allowed. if you 
do readonly sandbox=someuser you will get errors all around.
 USER variable value is untouched (looking at the code); the find_varibale 
calls return the sandbox entry, as they should.

pg

On 27 Apr 2016, at 14:41, Grisha Levit wrote:

> On Wed, Apr 27, 2016 at 7:37 AM, Piotr Grzybowski  wrote:
> 
> 
> 
>  It seems to me that creating the reference should be allowed, but the access 
> to the referenced variable should honor its attributes.
> 
> 
> Once you convert the variable to a reference, you can control its value by 
> modifying the value of a different variable with the name that corresponds to 
> the value of the readonly variable, so “access to the referenced variable 
> should honor its attributes” probably won’t do much (If I understand your 
> suggestion correctly).
> 
> In a less convoluted example that doesn’t rely on creating our own namerefs:
> 
> readonly
>  USER=sandbox
> 
> USER=root   
> # bash: USER: readonly variable
> 
> 
> 
> declare
>  -n USER
> sandbox=root
> # works
> 
> USER=root   
> # works
> 
> 
> [[ 
> $USER == root ]] # 0
> 
> 
> 
> # USER is unchanged, other than the -n attribute
> declare -p USER # declare -nrx USER="sandbox"
> The above works when the readonly variable has a value that is also a valid 
> identifier. In my previous example I worked around this using the fact that 
> ref=; declare -n ref does not check to make sure that $ref is a 
> valid identifier.
> 
> So:
> 
> readonly
>  PATH=/opt/bin
> 
> ref=
> $PATH
> declare
>  -n ref
> ref=/usr/bin
> 
> declare -p /opt/bin  # declare -- /opt/bin="/usr/bin"
> 
> 
> 
> declare -n PATH  # declare -nr PATH="/opt/bin"
> echo $PATH   # /usr/bin




Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Grisha Levit
On Wed, Apr 27, 2016 at 2:43 PM, Eduardo A. Bustamante López <
dual...@gmail.com> wrote:

> The attached patch seems to take care of at least these two cases:
>

I don't think legal_identifier is the correct test here since references to
array subscripts or array[@] are valid.


Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Eduardo A . Bustamante López
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/



Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Piotr Grzybowski
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: [..]
> But I think Chet already considered this, given that the check in declare.def
> was '#if 0'ed out.

 maybe for a reason, after your patch:

bash-4.4$ declare -n r
bash-4.4$ declare -n r
bash: `(null)': not a valid identifier

followed by exit(1)
 It seems to me that this whole nameref business is a bit messy.

pg





Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Grisha Levit
On Wed, Apr 27, 2016 at 3:10 PM, Eduardo A. Bustamante López <
dual...@gmail.com> wrote:

> On Mon, Apr 25, 2016 at 03:48:17PM -0400, Grisha Levit wrote:
> > # Expected behavior:set -- 1 2 3echo ${@@A} # set -- '1' '2'
>
> This is actually expected behaviour.


Sorry, that was confusing.  I included the expected (and observed) behavior
for comparison to the unexpected behavior that followed.  That is, after
the declare/ref= statements, the expected behavior was no longer observed.


Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Eduardo A . Bustamante López
On Mon, Apr 25, 2016 at 03:48:17PM -0400, Grisha Levit wrote:
> There seems to be a bug that if an array variable with a name matching one
> of the special single-character variables exists, then that variable is
> used during substring expansion and parameter transformation.
[...]
> # Expected behavior:set -- 1 2 3echo ${@@A} # set -- '1' '2'
> '3'echo ${@:0} # bash 1 2 3
[...]

This is actually expected behaviour. The @ parameter is a special case, with $0
being argv[0]. Normally, if you do "$@" it will expand to "$1" "$2" ... "$n",
without including $0. But in this case you're forcing it to expand from $0.

-- 
Eduardo Bustamante
https://dualbus.me/



Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Piotr Grzybowski
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





Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Eduardo A . Bustamante López
The attached patch seems to take care of at least these two cases:

|  dualbus@hp ...src/gnu/bash % ./bash --norc --noprofile -c 'r=@; declare -n r'
|  ./bash: line 0: declare: @: invalid variable name for name reference
|  
|  dualbus@hp ...src/gnu/bash % ./bash --norc --noprofile -c 'declare -n r; r=@'
|  ./bash: `@': not a valid identifier
|  
|  dualbus@hp ...src/gnu/bash % ./bash --norc --noprofile -c 'declare -n r; 
r=$(echo @)'
|  ./bash: `@': not a valid identifier

But I think Chet already considered this, given that the check in declare.def
was '#if 0'ed out.

-- 
Eduardo Bustamante
https://dualbus.me/
diff --git a/builtins/declare.def b/builtins/declare.def
index a1e9b4e..2ae12a8 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -570,7 +570,7 @@ declare_internal (list, local_var)
}
  else if (flags_on & att_nameref)
{
-#if 0
+#if 1
  if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) 
== 0 && legal_identifier (value_cell (var)) == 0)
{
  builtin_error (_("%s: invalid variable name for name 
reference"), value_cell (var));
diff --git a/variables.c b/variables.c
index 69ed170..dd62d96 100644
--- a/variables.c
+++ b/variables.c
@@ -2628,9 +2628,13 @@ bind_variable_internal (name, value, table, hflags, 
aflags)
 }
 
   /* The first clause handles `declare -n ref; ref=x;' */
-  if (entry && invisible_p (entry) && nameref_p (entry))
+  if (entry && invisible_p (entry) && nameref_p (entry)) {
+if(!legal_identifier(value)) {
+internal_error (_("`%s': not a valid identifier"), value);
+exit(1);
+}
 goto assign_value;
-  else if (entry && nameref_p (entry))
+  } else if (entry && nameref_p (entry))
 {
   newval = nameref_cell (entry);
 #if defined (ARRAY_VARS)


Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Eduardo A . Bustamante López
On Wed, Apr 27, 2016 at 08:41:20AM -0400, Grisha Levit wrote:
[...]
> The above works when the readonly variable has a value that is also a valid
> identifier. In my previous example I worked around this using the fact
> that ref=;
> declare -n ref does not check to make sure that $ref is a valid identifier.
[...]

It does seem to check, but only when you do: declare -n ref=

|  dualbus@hp ...src/gnu/bash % gdb ./bash --batch -ex 'b sh_invalidid' -ex r 
--args bash -c 'declare -n r=@'  
|  Breakpoint 1 at 0x493107: file common.c, line 236.
|  
|  Breakpoint 1, sh_invalidid (s=0x7dd26a "@") at common.c:236
|  236   builtin_error (_("`%s': not a valid identifier"), s);
|
|  dualbus@hp ...src/gnu/bash % gdb ./bash --batch -ex 'b sh_invalidid' -ex r 
--args bash -c 'declare -n r; r=@' 
|  Breakpoint 1 at 0x493107: file common.c, line 236.
|  [Inferior 1 (process 5609) exited normally]

As you can see, in the first case, it hits the sh_invalidid breakpoint, and
bash actually complains about the invalid identifier.

-- 
Eduardo Bustamante
https://dualbus.me/



Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Piotr Grzybowski
Hi,

On 27 Apr 2016, at 14:41, Grisha Levit wrote:

> Once you convert the variable to a reference, you can control its value by 
> modifying the value of a different variable with the name that corresponds to 
> the value of the readonly variable, so “access to the referenced variable 
> should honor its attributes” probably won’t do much (If I understand your 
> suggestion correctly).

 well, now after having looked at the code I am not that smart anymore.
 I see your point, but on one hand you are creating this reference loop on 
purpose, yet still something should be forbidden here. I like the idea of the 
references less and less, especially at the current state of the affairs in the 
variable model the introduction of these constructs is risky.
 Maybe it is possible to do it in a smart way.

cheers,
pg






Re: param expansion with single-character special vars in the environment

2016-04-27 Thread Grisha Levit
On Wed, Apr 27, 2016 at 7:37 AM, Piotr Grzybowski 
wrote:

 It seems to me that creating the reference should be allowed, but the
> access to the referenced variable should honor its attributes.
>
Once you convert the variable to a reference, you can control its value by
modifying the value of a different variable with the name that corresponds
to the value of the readonly variable, so “access to the referenced
variable should honor its attributes” probably won’t do much (If I
understand your suggestion correctly).

In a less convoluted example that doesn’t rely on creating our own namerefs:

readonly USER=sandbox

USER=root   # bash: USER: readonly variable
declare -n USER
sandbox=root# works
USER=root   # works

[[ $USER == root ]] # 0
# USER is unchanged, other than the -n attributedeclare -p USER #
declare -nrx USER="sandbox"

--

The above works when the readonly variable has a value that is also a valid
identifier. In my previous example I worked around this using the fact
that ref=;
declare -n ref does not check to make sure that $ref is a valid identifier.

So:

readonly PATH=/opt/bin

ref=$PATHdeclare -n ref
ref=/usr/bindeclare -p /opt/bin  # declare -- /opt/bin="/usr/bin"
declare -n PATH  # declare -nr PATH="/opt/bin"echo $PATH
# /usr/bin

​


Re: param expansion with single-character special vars in the environment

2016-04-25 Thread Grisha Levit
A related issue is with adding the nameref attribute to a readonly
variable. Not sure if that should be allowed, as it can be used to change
the meaning of the variable, even for variables that bash is using
internally:

$ TIMEFORMAT='%R'
$ time bash -c 'readonly TMOUT=5; read'5.007
$ time bash -c 'readonly TMOUT=5; ref=$TMOUT; declare -n ref; ref=10;
declare -n TMOUT; read'10.004

The same technique works for circumventing PATH in a restricted shell:

$ PATH='/restricted/bin' $BASH -r -c 'type sed; ref=$PATH; declare -n
ref; ref=/usr/bin; declare -n PATH; type sed' bash
bash: line 0: type: sed: not found
sed is /usr/bin/sed

​