Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread Pedro Gimeno
Bash Version: 4.2
Patch Level: 37
Release Status: release

Description:
If a file with a command that ends in \newline is sourced, the next
command issued in the command line does not interpret aliases but
subsequent ones do. It's a minor issue easy to work around, but since
it's surprising behaviour and some aliases are important, I thought I'd
report it. In the real case where I used it, the command was 'rm' which
was an alias to 'rm -i' to ask for confirmation, and it didn't ask.

Repeat-By:
$ alias hi=echo\ hello
$ echo /bin/true\\  testbug.sh
$ hi
hello
$ source testbug.sh
$ hi
bash: hi: command not found
$ hi
hello



Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread Pedro Gimeno
Bash Version: 4.2
Patch Level: 37
Release Status: release

Description:
If a file with a command that ends in \newline is sourced, the next
command issued in the command line does not interpret aliases but
subsequent ones do. It's a minor issue easy to work around, but since
it's surprising behaviour and some aliases are important, I thought I'd
report it. In the real case where I used it, the command was 'rm' which
was an alias to 'rm -i' to ask for confirmation, and it didn't ask.

Repeat-By:
$ alias hi=echo\ hello
$ echo /bin/true\\  testbug.sh
$ hi
hello
$ source testbug.sh
$ hi
bash: hi: command not found
$ hi
hello



Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread John McKown
On Thu, Apr 2, 2015 at 4:40 PM, Pedro Gimeno
pgwr-...@personal.formauri.es wrote:
 Bash Version: 4.2
 Patch Level: 37
 Release Status: release

 Description:
 If a file with a command that ends in \newline is sourced, the next
 command issued in the command line does not interpret aliases but
 subsequent ones do. It's a minor issue easy to work around, but since
 it's surprising behaviour and some aliases are important, I thought I'd
 report it. In the real case where I used it, the command was 'rm' which
 was an alias to 'rm -i' to ask for confirmation, and it didn't ask.

 Repeat-By:
 $ alias hi=echo\ hello
 $ echo /bin/true\\  testbug.sh
 $ hi
 hello
 $ source testbug.sh
 $ hi
 bash: hi: command not found
 $ hi
 hello


Interesting. does the same on my system, but notice something in the
following cut'n'paste

[tsh009@it-johnmckown-linux junk]$ echo /bin/true\\ testbug.sh
[tsh009@it-johnmckown-linux junk]$ od -tcx1 testbug.sh
000   /   b   i   n   /   t   r   u   e   \  \n
 2f  62  69  6e  2f  74  72  75  65  5c  0a
013

Note that testbug.sh does end in a LF, at least if I did it correctly.
Also notice in the following transcript:

[tsh009@it-johnmckown-linux junk]$ echo -n /bin/true |testbug.sh
[tsh009@it-johnmckown-linux junk]$ od -tcx1 testbug.sh
000   /   b   i   n   /   t   r   u   e
 2f  62  69  6e  2f  74  72  75  65
011
[tsh009@it-johnmckown-linux junk]$ source testbug.sh
[tsh009@it-johnmckown-linux junk]$ hi
hello
[tsh009@it-johnmckown-linux junk]$

In this case, testbug.sh truly does NOT have an LF at the end, and
there is no problem.

Also notice, all by itself, not preceded by the source command:

[tsh009@it-johnmckown-linux junk]$ \hi
bash: hi: command not found...
[tsh009@it-johnmckown-linux junk]$

Also notice:

[tsh009@it-johnmckown-linux junk]$ hi
bash: hi: command not found...

Which is expected since enclosing the command in .. is quoted,
which disables expanding aliases

Since testbug.sh terminates with a \, it appears that the BASH shell
is seeing your second command as \hi. Which _appears to me_ is what
BASH would call a quoted value. And it is documented that aliases
are not expanded when quoted.


-- 
If you sent twitter messages while exploring, are you on a textpedition?

He's about as useful as a wax frying pan.

10 to the 12th power microphones = 1 Megaphone

Maranatha! 
John McKown



Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread Eduardo A . Bustamante López
I'm replying to this report, because it's the latest.

This seems to be caused by last_read_token having an incorrect value set.
`alias_expand_token' in parse.y relies on
`command_token_position (last_read_token)' (and parser_state), to determine if
an alias expansion should be performed.

The correct value of last_read_token there should be of 10:

  alias_expand_token: last_read_token = 10

But, for some reason (I don't know if it's parse_and_execute or
parse_command), after calling `evalstring', this value isn't restored to the
correct one (shouldn't we care about toplevel's parser status?).

Anyways, I wasn't able to produce a patch for this, because I don't know where
last_read_token should be reset, or if there's some magic unwind_protect code
to restore the tokens to the value before calling source/eval, but I hope this
information makes it easier for Chet to produce a patch.


Also, while looking at this, I found this:

dualbus@yaqui ~ % bash -c 'eval \\; echo y'
y
dualbus@yaqui ~ % bash -ic 'eval \\; echo y'
exit

So, that eval is triggering a yacc_EOF, so that triggers the `exit' in the
interactive shell.

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



Re: Sourcing a file ending in \newline disables aliases for 1 command

2015-04-03 Thread Pedro Gimeno
John McKown wrote, On 2015-04-03 14:19:
 Note that testbug.sh does end in a LF, at least if I did it correctly.

I've noticed that actually the LF is not important, only the final
backslash is:

$ alias hi=echo\ hello

Without final LF:

$ echo -n true\\  testbug.sh
$ . testbug.sh
$ hi
bash: hi: command not found
$ hi
hello

With final LF (same case as initially submitted):

$ echo true\\  testbug.sh
$ . testbug.sh
$ hi
bash: hi: command not found
$ hi
hello

But if there is one more LF it doesn't reproduce:

$ echo true\\  testbug.sh
$ echo  testbug.sh
$ . testbug.sh
$ hi
hello

In the first case the file is malformed, so that's not a problem. I
think the second case should act as if the last command was in a line by
itself without a terminating newline, but that's not what happens. It
can also be argued that in that case the file is malformed too.

In my real use case, the last lines were a set of options to which I was
constantly adding or removing, with a backslash at the end of each line.
At one point I wasn't careful and didn't remove the backslash from the
last line. As I said, the next thing I did was to delete a file, and
that's how I noticed it didn't prompt me for confirmation.

I can easily add a ; in one line alone at the end of the file and insert
the options before it. That'd work around this.

 Since testbug.sh terminates with a \, it appears that the BASH shell
 is seeing your second command as \hi. Which _appears to me_ is what
 BASH would call a quoted value. And it is documented that aliases
 are not expanded when quoted.

On the other hand, this works as expected:

$ echo true\\  testbug.sh
$ . testbug.sh
$ hi
bash: hi: command not found

My point with this last example is that it's not quoting the double
quotes as if they were prefixed with a backslash. This is what happens
when that's the case:

$ \hi


So it's not as simple as it acts as if preceded by a backslash.

Also, it doesn't reproduce if the aliased command is inside the sourced
file:

$ echo true\\  testbug.sh
$ echo hi  testbug.sh
$ . testbug.sh
bash: truehi: command not found

(which is expected).

$ echo true\\  testbug.sh
$ echo  testbug.sh
$ echo hi  testbug.sh
$ . testbug.sh
hello

(which is expected too).




Regression with declare -i and arrays

2015-04-03 Thread Eduardo A . Bustamante López
Hello Chet,

You introduced a regression:

[dual...@ma.sdf.org /tmp/tmp.ps6HXrLSZX/devel-]$ ./bash -c 'typeset -i x; 
x=([0]=1+1); echo $x'
1+1

vs

dualbus@yaqui ~ % bash -c 'typeset -i x; x=([0]=1+1); echo $x' 
2

The regression was introduced here: 06c3a57511953d09ac9ea262bc18bfdbcff23fc4

The patch that causes it:

diff --git a/builtins/declare.def b/builtins/declare.def
index 69c4703..5ed83a0 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -506,13 +506,13 @@ declare_internal (list, local_var)
if (flags_on  att_assoc)
{
  var = make_new_assoc_variable (name);
- if (offset == 0  no_invisible_vars == 0)
+ if (var  offset == 0  no_invisible_vars == 0)
VSETATTR (var, att_invisible);
}
else if ((flags_on  att_array) || making_array_special)
{
  var = make_new_array_variable (name);
- if (offset == 0  no_invisible_vars == 0)
+ if (var  offset == 0  no_invisible_vars == 0)
VSETATTR (var, att_invisible);
}
else
@@ -522,9 +522,11 @@ declare_internal (list, local_var)
else
{
  var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : 
bind_variable (name, (char *)NULL, 0);
- if (no_invisible_vars == 0)
+ if (var  no_invisible_vars == 0)
VSETATTR (var, att_invisible);
}
+   if (var == 0)
+   NEXT_VARIABLE ();
  }
/* Can't take an existing array variable and make it a nameref */
else if ((array_p (var) || assoc_p (var))  (flags_on  att_nameref))


Thanks to Geir, because he split the commits into logical commits and I was 
able to find this faster with git bisect.

I caught it by running: make tests

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



Re: Regression with declare -i and arrays

2015-04-03 Thread Eduardo Bustamante
Nevermind. The patch is wrong, but at least it shows where the problem is
(if needs braces, around line 529)
El abr 3, 2015 8:48 PM, Eduardo A. Bustamante López dual...@gmail.com
escribió:

 Here's a patch:


 diff --git a/builtins/declare.def b/builtins/declare.def
 index 5ed83a0..f0f9a6d 100644
 --- a/builtins/declare.def
 +++ b/builtins/declare.def
 @@ -280,7 +280,7 @@ declare_internal (list, local_var)
return (sh_chkwrite (any_failed ? EXECUTION_FAILURE :
 EXECUTION_SUCCESS));
  }

 -#define NEXT_VARIABLE() free (name); list = list-next; continue
 +#define NEXT_VARIABLE() do { free (name); list = list-next; continue; }
 while(0)

/* There are arguments left, so we are making variables. */
while (list) /* declare [-aAfFirx] name [name ...] */

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



Re: Regression with declare -i and arrays

2015-04-03 Thread Eduardo A . Bustamante López
Here's a patch:


diff --git a/builtins/declare.def b/builtins/declare.def
index 5ed83a0..f0f9a6d 100644
--- a/builtins/declare.def
+++ b/builtins/declare.def
@@ -280,7 +280,7 @@ declare_internal (list, local_var)
   return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : 
EXECUTION_SUCCESS));
 }
 
-#define NEXT_VARIABLE() free (name); list = list-next; continue
+#define NEXT_VARIABLE() do { free (name); list = list-next; continue; } 
while(0)
 
   /* There are arguments left, so we are making variables. */
   while (list) /* declare [-aAfFirx] name [name ...] */

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