Re: Bash 5.2.21 segfaults when I feed it garbage

2024-01-12 Thread Chet Ramey

On 1/10/24 2:06 PM, Grisha Levit wrote:


Rewriting the original report as:

 bash <<<'((X=([))'

even after the last fix, there's still a similar issue with input like:

 bash <<<'((X=([))]'


Thanks for the report. I debated whether or not to do error handling before
restoring the parser state; this makes up my mind.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: nofork command substitution bugs

2024-01-12 Thread Chet Ramey

On 1/12/24 1:06 PM, Oğuz wrote:


Why would that be unexpected, since you're explicitly running something
in the calling shell's context, with the expected side effects to that
environment?


I wasn't clear. This doesn't exit the shell

 bash-5.3$ exec foo
 bash: exec: foo: not found
 bash-5.3$

This does:

 bash-5.3$ : ${ exec foo;}
 bash: exec: foo: not found
 $

Why would you expect either to cause an interactive shell to exit?


Oh, I see, an interactive shell. Think of funsubs in an interactive shell
as being temporarily non-interactive, like when the shell executes
./source. If you source a file from an interactive shell, a failed exec
causes the shell to exit.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: document that read built-in can't return zero-length string in the middle of input

2024-01-12 Thread Greg Wooledge
On Sat, Jan 13, 2024 at 02:06:08AM +0700, Robert Elz wrote:
> Date:Fri, 12 Jan 2024 07:15:35 -0500
> From:Greg Wooledge 
> Message-ID:  
> 
>   | This was one of the things I tested:
> 
> Perhaps intended to, but didn't, or not in this example:
> 
>   | { read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY a b c
> 
> Rewrite that, correctly for the purpose, as:
> 
> { read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY b c
> 
> or a bit more cleanly as:
> 
> { read -N1; read -r b c; } < <(printf '\\\nabc'); declare -p REPLY b c

Yes, I made an error there.  Sorry for the confusion.

However, you're testing something slightly different from what I was
testing.  Here's what I originally intended:

unicorn:~$ { read -N1; read -r b c; } < <(printf %s \\nabc); declare -p REPLY b 
c
declare -- REPLY="n"
declare -- b="abc"
declare -- c=""

The important part of the result, for me, is that read -N1 still consumes
two characters of input, and stores one character into the variable.
The stored character is 'n' instead of a newline, after fixing the test.

And here's what you thought I was trying to test:

unicorn:~$ { read -N1; read -r b c; } < <(printf %s $'\\\nabc'); declare -p 
REPLY b c
declare -- REPLY="a"
declare -- b="bc"
declare -- c=""

In this case, read -N1 consumes *three* characters of input, and stores
one character into the variable.  So the character count difference is
even more dramatic.

> ps: the use of process substitution there is just silly, it would work
> just as well, and be easier to understand if written:
> 
>   printf '\\\nabc' | { read -N1; read -r b c; }; declare -p REPLY b c

That requires lastpipe, or moving the declare -p inside the curly braces.

> or{ read -N1; read -r b c; } <<< $'\\\nabc' ; declare -p REPLY b c

<<< unavoidably adds a newline character to the input, which isn't
actually harmful in this case, but isn't what I was trying to test.
I generally go with < <(printf %s ...) when I want to send input that
may not end with a newline.  I simply forgot the %s.

I actually ran several tests before this, which I didn't show in the
previous email.  The first was:

unicorn:~$ { read -r -N1 a b c; } < <(printf abc); declare -p a b c
declare -- a="a"
declare -- b=""
declare -- c=""

I kept making changes to this, ultimately ending up with the test with
the error in it.  I should've started with printf %s in the first place,
but I was lazy.  There's a lesson somewhere in there.

In any case, the important part of this thread is the proposed
documentation change.  My wording may not be ideal, so if you have
any improvement suggestions, feel free to make them.



Re: document that read built-in can't return zero-length string in the middle of input

2024-01-12 Thread Lawrence Velázquez
On Fri, Jan 12, 2024, at 2:06 PM, Robert Elz wrote:
> ps: the use of process substitution there is just silly, it would work
> just as well, and be easier to understand if written:
>
>   printf '\\\nabc' | { read -N1; read -r b c; }; declare -p REPLY b c

Presumably Greg was just preventing the implicit pipeline subshell
from swallowing the variables.

bash-5.2$ printf '\\\nabc' | { read -N1; read -r b c; }; declare -p 
REPLY b c
bash: declare: REPLY: not found
bash: declare: b: not found
bash: declare: c: not found

For these self-contained experiments, printing the values from
within the subshell is probably fine.

bash-5.2$ printf '\\\nabc' | { read -N1; read -r b c; declare -p REPLY 
b c; }
declare -- REPLY="a"
declare -- b="bc"
declare -- c=""

-- 
vq



Re: document that read built-in can't return zero-length string in the middle of input

2024-01-12 Thread Robert Elz
Date:Fri, 12 Jan 2024 07:15:35 -0500
From:Greg Wooledge 
Message-ID:  

  | This was one of the things I tested:

Perhaps intended to, but didn't, or not in this example:

  | { read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY a b c

Rewrite that, correctly for the purpose, as:

{ read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY b c

or a bit more cleanly as:

{ read -N1; read -r b c; } < <(printf '\\\nabc'); declare -p REPLY b c

and (both cases) you get:

declare -- REPLY="a"
declare -- b="bc"
declare -- c=""

bash is (as I assumed earlier it would) doing the correct thing, and
ignoring the elided newline completely.   If it didn't, that would have
been a bug, but it does, so all is well.

In the case you tested, printf output $'\nabc' and read -N1 correctly
read the first char (\n) into REPLY (and then read abc into b, 'c' isn't
really needed for this example).

[Note: I deleted the output of 'a' as I didn't conveniently have a
variable called 'a' defined, so declare issued an error, which would
have just confused things.]

kre

ps: the use of process substitution there is just silly, it would work
just as well, and be easier to understand if written:

printf '\\\nabc' | { read -N1; read -r b c; }; declare -p REPLY b c
or  { read -N1; read -r b c; } <<< $'\\\nabc' ; declare -p REPLY b c

I much prefer the former of those two.





Re: nofork command substitution bugs

2024-01-12 Thread Oğuz
On Fri, Jan 12, 2024 at 7:05 PM Chet Ramey  wrote:
> Nofork command substitution freezes the jobs list, because you don't
> want jobs appearing and disappearing in the list while you're running
> word expansion. If the jobs list is frozen, wait -n doesn't even try
> waiting, since you don't want jobs removed from the list in, say, a
> SIGCHLD trap. I think it's ok to do the wait but not delete the job,
> regardless of what posix says, so I'll make that change for funsubs.

Sounds good, thanks.

> Why would that be unexpected, since you're explicitly running something
> in the calling shell's context, with the expected side effects to that
> environment?

I wasn't clear. This doesn't exit the shell

bash-5.3$ exec foo
bash: exec: foo: not found
bash-5.3$

This does:

bash-5.3$ : ${ exec foo;}
bash: exec: foo: not found
$

Why would you expect either to cause an interactive shell to exit?



Re: No filename expansion in shell-expand-line

2024-01-12 Thread Chet Ramey

On 1/12/24 3:28 AM, Martin Schulte wrote:

Hello,

from the documentation I understand that shell-expand-line (ESC CTRL-E) should 
do alias expansion, history expansion, brace expansion, tilde expansion, shell 
parameter expansion, command substitution, arithmetic expansion, process 
substitution (if supported by the operation system), word splitting, filename 
expansion and quote removal.


It doesn't do filename expansion and never has, going all the way back
to when it was first added in 1989, and the current man page doesn't
include it in the enumerated list of expansions it performs:

shell-expand-line (M-C-e)
   Expand the line by performing shell word expansions.  This  per-
   forms alias and history expansion, $'string' and $"string" quot-
   ing, tilde expansion, parameter and variable  expansion,  arith-
   metic expansion, word splitting, and quote removal.  See HISTORY
   EXPANSION below for a description of history expansion.

This is an update from the bash-5.2 man page, the result of

https://lists.gnu.org/archive/html/bug-bash/2023-03/msg00031.html

There's a separate bindable command to perform filename expansion.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: nofork command substitution bugs

2024-01-12 Thread Chet Ramey

On 1/4/24 8:36 AM, Oğuz wrote:

These bugs affect the development branch only.

1. `wait -n' doesn't work inside nofork command substitution. I think
it should, or wait without `-n' shouldn't work either, or what works
and what doesn't should be documented.


Nofork command substitution freezes the jobs list, because you don't
want jobs appearing and disappearing in the list while you're running
word expansion. If the jobs list is frozen, wait -n doesn't even try
waiting, since you don't want jobs removed from the list in, say, a
SIGCHLD trap. I think it's ok to do the wait but not delete the job,
regardless of what posix says, so I'll make that change for funsubs.



 $ sleep 3 & sleep 1; echo ${| wait -n -p REPLY;}
 [1] 433

 $
 [1]+  Donesleep 3
 $


2. Sending a signal other than SIGTERM to an asynchronous process
created inside nofork command substitution kills the parent shell.
This should not happen.


Everything in a command substitution is in the same process group as the
parent shell, since word expansions are performed by the parent shell and
command substitution is a synchronous operation. As a result, asynchronous
processes in nofork command substitutions aren't run in a separate process
group when job control is active. If you send a signal to the process
group, the shell gets it, too. I'm not sure of the right approach here;
I'll have to think about it.



There are other cases where the parent shell exits unexpectedly, such
as when the exec command fails inside nofork command substitution, but
I'm not sure if those are bugs or intended behavior.


Why would that be unexpected, since you're explicitly running something
in the calling shell's context, with the expected side effects to that
environment?



3. Linking REPLY to a variable inside nofork command substitution
renders the target variable unset. I don't think this should be the
case; and if it has to, it should be documented.


I agree; I don't think the implicit creation of REPLY as a local variable
should follow namerefs here.

Chet

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: document that read built-in can't return zero-length string in the middle of input

2024-01-12 Thread Greg Wooledge
On Fri, Jan 12, 2024 at 03:26:31PM +0700, Robert Elz wrote:
> Date:Thu, 11 Jan 2024 20:02:04 -0500
> From:Greg Wooledge 
> Message-ID:  
> 
>   | What actually counts is how many
>   | characters are *stored* in the variable, not how many characters are
>   | *read* from the input.
> 
> I suspect that is the root of the issue here, you're considering
> the word "read" to mean read(2) whereas as it is in the documentation
> for the read command, I suspect it means that one, how many characters
> the read command obtains, rather than how many the read system call
> processes (like elided newlines. when -r is not used, would also not
> be counted, or expected to be, right?)

This was one of the things I tested:


unicorn:~$ { read -N1; read -r b c; } < <(printf \\nabc); declare -p REPLY a b 
cdeclare -- REPLY=$'\n'
declare -- a=$'\n'
declare -- b="abc"
declare -- c=""


(The value of 'a' was from a previous test.)  read -N1 consumed two
characters of the input, and stored one character in the variable.
As a script writer, those are the things I care about.  I don't know
or care about the internals of the shell.

Also note that I'm assuming the implementation isn't going to change,
and that our sole goal in this thread is to document its behavior.
Therefore I don't speak about what's "expected" -- merely what is.

I would, however, strongly recommend that script writers who use
read -N *always* include the -r option.



Re: No filename expansion in shell-expand-line

2024-01-12 Thread Martin Schulte
Sorry, I falied to copy and paste R*, the last line is replaced by

ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 hello 
R*

> Hello,
> 
> from the documentation I understand that shell-expand-line (ESC CTRL-E) 
> should do alias expansion, history expansion, brace expansion, tilde 
> expansion, shell parameter expansion, command substitution, arithmetic 
> expansion, process substitution (if supported by the operation system), word 
> splitting, filename expansion and quote removal.
> 
> $ echo $BASH_VERSION
> 5.2.15(1)-release
> $ echo R*
> README
> $ echo
> 
> $ ls !! {a..c} ~root $TERM $(date +%F) $((6*7)) <(cat /etc/passwd) "hello" R*
> 
> After pressing ESC CTRL-E the last line is replaced by:
> 
> ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 
> hello
> 
> So, everything works fine execept filename expansion, which seems to be 
> missing.
> 
> Or do I understand something wrong?
> 
> Best regards,
> 
> Martin



No filename expansion in shell-expand-line

2024-01-12 Thread Martin Schulte
Hello,

from the documentation I understand that shell-expand-line (ESC CTRL-E) should 
do alias expansion, history expansion, brace expansion, tilde expansion, shell 
parameter expansion, command substitution, arithmetic expansion, process 
substitution (if supported by the operation system), word splitting, filename 
expansion and quote removal.

$ echo $BASH_VERSION
5.2.15(1)-release
$ echo R*
README
$ echo

$ ls !! {a..c} ~root $TERM $(date +%F) $((6*7)) <(cat /etc/passwd) "hello" R*

After pressing ESC CTRL-E the last line is replaced by:

ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 hello

So, everything works fine execept filename expansion, which seems to be missing.

Or do I understand something wrong?

Best regards,

Martin



Re: document that read built-in can't return zero-length string in the middle of input

2024-01-12 Thread Robert Elz
Date:Thu, 11 Jan 2024 20:02:04 -0500
From:Greg Wooledge 
Message-ID:  

  | What actually counts is how many
  | characters are *stored* in the variable, not how many characters are
  | *read* from the input.

I suspect that is the root of the issue here, you're considering
the word "read" to mean read(2) whereas as it is in the documentation
for the read command, I suspect it means that one, how many characters
the read command obtains, rather than how many the read system call
processes (like elided newlines. when -r is not used, would also not
be counted, or expected to be, right?)

kre