[Bug] Array declaration only includes first element

2024-07-18 Thread Charles Dong via Bug reports for the GNU Bourne Again SHell
Hello,

I would like to report an unexpected behavior with array declaration on latest 
Bash, which is very likely to be a bug. I discovered this when I found Pinentry 
could not display GUI windows properly.

- Bash version: 5.2.26(1)-release
- OS: Arch Linux (Kernel: 6.9.9-arch1-1) (My PC), and Termux (My phone)

Steps to reproduce:

- Declare an array: `a=(aa bb cc dd)`
- Print this array: `echo $a` or `printf $a`

Expected behavior:

Output `aa bb cc dd`

Actual behavior:

Output `aa` only

I hope my information can help.

Kind Regards,
Charles

Sent with [Proton Mail](https://proton.me/) secure email.

Re: [Bug] Array declaration only includes first element

2024-07-18 Thread Greg Wooledge
On Thu, Jul 18, 2024 at 00:00:17 +, Charles Dong via Bug reports for the 
GNU Bourne Again SHell wrote:
> - Declare an array: `a=(aa bb cc dd)`
> - Print this array: `echo $a` or `printf $a`

$a is equivalent to ${a[0]}.  That's not how you print an entire array.

The easiest way to print an array is to use "declare -p":

hobbit:~$ a=(aa bb cc dd)
hobbit:~$ declare -p a
declare -a a=([0]="aa" [1]="bb" [2]="cc" [3]="dd")

If you want something a little less noisy, you can use "${a[*]}" to
serialize the whole array to a single string/word, or "${a[@]}" with
the double quotes to expand it to a list of words.

hobbit:~$ echo "<<${a[*]}>>"
<>
hobbit:~$ printf '<<%s>> ' "${a[@]}"; echo
<> <> <> <> 

See also .



Re: proposed BASH_SOURCE_PATH

2024-07-18 Thread Chet Ramey

On 7/11/24 3:51 AM, konsolebox wrote:

On Thu, Jul 11, 2024 at 4:08 AM Chet Ramey  wrote:

and the BASH_SOURCE
absolute pathname discussion has been bananas, so that's not going in any
time soon.


Maybe just create BASH_SOURCE_REAL instead to avoid the gripes.


I don't think so. It's not very useful to have two variables that are so
similar -- it's needless overhead.

--
``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: [Bug] Array declaration only includes first element

2024-07-18 Thread Lawrence Velázquez
On Thu, Jul 18, 2024, at 8:57 AM, Greg Wooledge wrote:
> $a is equivalent to ${a[0]}.

This is documented, by the way.  It is not a bug.

"Referencing an array variable without a subscript is equivalent to referencing 
with a subscript of 0."

https://www.gnu.org/software/bash/manual/html_node/Arrays.html

-- 
vq



Re: waiting for process substitutions

2024-07-18 Thread Chet Ramey

On 7/14/24 8:40 PM, Zachary Santer wrote:


On Fri, Jul 5, 2024 at 2:38 PM Chet Ramey  wrote:


There is code tagged
for bash-5.4 that allows `wait -n' to look at these exited processes as
long as it's given an explicit set of pid arguments.


I agree with all the knowledgeable people here telling you that the
way 'wait -n' is still implemented in bash-5.3-alpha is obviously
wrong, but I also want to point out that the way you plan to change
its behavior in bash-5.4 still won't allow Greg's example below to
work reliably.


OK, but how would you do that? If a job has already terminated, and been
removed from the jobs list, how would you know that `wait -n' without pid
arguments should return it? There can be an arbitrary number of pids on
the list of saved pids and statuses -- the only way to clear it using wait
is to run `wait' without arguments.

You can say not to remove the job from the jobs list, which gets into the
same notification issues that originally started this discussion back in
January, and I have made a couple of changes in that area in response to
the original report that I think will address some of those. But once you
move the job from the jobs list to this list of saved pids, `wait' without
-n or pid arguments won't look for it any more (and will clear the list 
when it completes). Why should `wait -n' without pid arguments do so?




On Fri, Jul 12, 2024 at 9:06 PM Greg Wooledge  wrote:


greg@remote:~$ cat ~greybot/factoids/wait-n; echo
Run up to 5 processes in parallel (bash 4.3): i=0 j=5; for elem in "${array[@]}"; do (( i++ < 
j )) || wait -n; my_job "$elem" & done; wait


He'd have to do something like this:
set -o noglob
i=0 j=5
declare -a pid_set=()
for elem in "${array[@]}"; do
   if (( ! i++ < j )); then
 wait -n -p terminated_pid -- "${!pid_set[@]}"
 unset pid_set[terminated_pid]
   fi
   my_job "$elem" &
   pid_set[${!}]=''
done
wait

It's probably best that 'wait -n' without arguments and 'wait -n' with
explicit pid arguments have the same relationship to each other as
'wait' without arguments and 'wait' with explicit pid arguments.


That's pretty much what we're talking about here. `wait' without arguments
doesn't look in the list of saved statuses whether -n is supplied or not.
`wait' with pid argument should look in this list whether -n is supplied or
not. But see below for the differences between `wait' with and without pid
arguments whether -n is supplied or not.




In other words, process substitutions notwithstanding,
$ wait
and
$ wait -- "${all_child_pids[@]}"
do the same thing.


That's just not true, and they're not even defined to do the same thing.
If you ask for a specific pid argument, wait will return its exit status
even if the job it belongs to has been removed from the jobs list and
saved on the list of saved pids and statuses. wait without pid arguments
just makes sure there are no running child processes and clears the list of
saved statuses -- it has no reason to look at the saved pid list before it
clears it.



So,
$ wait -n
and
$ wait -n -- "${all_child_pids[@]}"
should also do the same thing.


One issue here is that wait without arguments clears the list of saved
statuses. `wait -n' without arguments doesn't do that, but it probably
should since it's now going to have access to that list, though it would
no doubt break some existing use cases.

The other issue is as above: why should `wait -n' with no pid arguments
do anything with processes on this list? And if you think it should, what
should it do with those processes?

--
``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: proposed BASH_SOURCE_PATH

2024-07-18 Thread konsolebox
On Thu, Jul 18, 2024 at 11:02 PM Chet Ramey  wrote:
>
> On 7/11/24 3:51 AM, konsolebox wrote:
> > On Thu, Jul 11, 2024 at 4:08 AM Chet Ramey  wrote:
> >> and the BASH_SOURCE
> >> absolute pathname discussion has been bananas, so that's not going in any
> >> time soon.
> >
> > Maybe just create BASH_SOURCE_REAL instead to avoid the gripes.
>
> I don't think so. It's not very useful to have two variables that are so
> similar -- it's needless overhead.

So I guess it's really now just about BASH_SOURCE.  What's the final
decision on this?  I don't think waiting for more input would make a
difference.


-- 
konsolebox



Re: waiting for process substitutions

2024-07-18 Thread Chet Ramey

On 7/14/24 8:40 PM, Zachary Santer wrote:


See my attachments, though. Something about my second set of process
substitutions is causing 'wait' without arguments to not wait for the
final procsub, whose pid is still in $! at the time.


There's an easy fix for this, thanks.

It's not in the set of changes to `wait -n' I just pushed, but it will be
in the next push.

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


[PATCH] malloc: fix out-of-bounds read

2024-07-18 Thread Collin Funk
Hi,

In lib/malloc/malloc.c there is a read that occurs 1 or 2 indexes before
the first element in the buffer. The issue is this macro:

/* Use this when we want to be sure that NB is in bucket NU. */
#define RIGHT_BUCKET(nb, nu) \
(((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))

Where 'binsizes' is an array like this:

static const unsigned long binsizes[NBUCKETS] = {
32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
... };

The out-of-bounds read occurs in a line like this:

  /* If ok, use the same block, just marking its size as changed.  */
  if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1))
{
  ...
}

Where 'nunits' isn't properly checked. This can easily be seen by
-fsanitize=undefined when running make check:

< malloc.c:1205:7: runtime error: index -1 out of bounds for type 'long 
unsigned int [28]'
< malloc.c:1205:39: runtime error: index -2 out of bounds for type 'long 
unsigned int [28]'
< malloc.c:1205:39: runtime error: index -1 out of bounds for type 'long 
unsigned int [28]'

I've attached a patch that silences ubsan atleast. I didn't look into
the surrounding code much so a double check would be nice. :)

Collin

>From 4863afd5260e11f05f69adc64c496f6d8bace627 Mon Sep 17 00:00:00 2001
From: Collin Funk 
Date: Thu, 18 Jul 2024 21:45:51 -0700
Subject: [PATCH] malloc: fix out-of-bounds read

* lib/malloc/malloc.c (internal_realloc): Check value of nunits before
using RIGHT_BUCKET.
---
 lib/malloc/malloc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/malloc/malloc.c b/lib/malloc/malloc.c
index 7b2c3f25..07487fa8 100644
--- a/lib/malloc/malloc.c
+++ b/lib/malloc/malloc.c
@@ -1202,7 +1202,8 @@ internal_realloc (PTR_T mem, size_t n, const char *file, int line, int flags)
   nbytes = ALLOCATED_BYTES(n);
 
   /* If ok, use the same block, just marking its size as changed.  */
-  if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1))
+  if ((1 <= nunits && RIGHT_BUCKET (nbytes, nunits))
+  || (2 <= nunits && RIGHT_BUCKET (nbytes, nunits - 1)))
 {
   /* Compensate for increment above. */
   m -= 4;
-- 
2.45.2



Re: pwd and prompt don't update after deleting current working directory

2024-07-18 Thread Martin D Kealey
TL;DR: what you are asking for is unsafe, and should never be added to any
published version of any shell.

On Tue, 16 Jul 2024 at 17:47, David Hedlund  wrote:

> Do you think that it would be appropriate to submit this feature request
> to the developers of the rm command instead.
>

This suggestion hints at some serious misunderstandings.

Firstly, under normal circumstances two processes cannot interfere with
each others' internal states (*1) - and yes, every process has a *separate*
current directory as part of its internal state.

*Most* of that internal state is copied from its parent when it starts,
which gives the illusion that the shell is changing things in its children,
but in reality, it's setting their starting conditions, and cannot
influence them thereafter.

Secondly, *most* commands that you type into a shell are separate programs,
not part of the shell. Moreover, the *terminal* is a separate program from
the shell, and they can only interact through the tty byte stream.

Thirdly, the kernel tracks the current directory on behalf of each process.
It tracks the directory by its identity, *not* by its name. (*2) This means
that you can do this:

$ mkdir /tmp/a
$ cd /tmp/a
$ mv ../a ../b
$ /bin/pwd
/tmp/b

Note that as an efficiency measure, the built-in *`pwd*` command and the
expansion `*$PWD*` give the answer cached by the most recent *cd*, so this
should be considered unreliable:

$ pwd
/tmp/a
$ cd -P .
$ pwd
/tmp/b

For comparision, caja (file manager in MATE) is stepping back as many
> directories as needed when it is located in a directory that is deleted in
> bash or caja.
>

Comparing programs with dissimilar purposes is, erm, unconvincing.

Caja's *first* purpose is to display information about a filesystem.
To make this more comprehensible to the user, it focuses on one directory
at a time. (*3)

Critically, every time you make a change, it shows you the results before
you can make another change.

That is pretty much the opposite of a shell.

Bash (like other shells) is primarily a scripting language and a command
line interface, whose purpose is to invoke other commands (some of which
may be built-ins (*4)). The shell is supposed to *do* things *without*
showing you what's happened. If you want to see the new state of the
system, you ask it to run a program such as `*pwd*` or `*ls*` to show you.
(*5)

Currently if a program is invoked in an unlinked current directory, most
likely it will complain but otherwise do nothing.
But if the shell were to surreptitiously change directory, a subsequent
command invoked in an unexpected current directory could wreak havoc,
including deleting or overwriting the wrong files or running the wrong
programs, and with no guarantee that there will be any warning indications.

All that said, if you want to risk breaking your own system, feel free to
add the relevant commands to `*PROMPT_COMMAND*` as suggested by other folk.

-Martin

*1: Okay, yes there are debugging facilities, but unless the target program
is compiled with debugging support, attempting to change the internal state
of the other program stands a fair chance of making it crash instead. You
certainly wouldn't want "rm" to cause your interactive shell to crash. And
there are signals, most of which default to making the target program
*intentionally
*crash.

*2: Linux's */proc/$pid/cwd* reconstructs the path upon request. Only when
it's deleted does it save the old path with "(deleted)" appended.

*3: It's not even clear that this focal directory is the kernel-level
current directory of the Caja process, but it probably is. I would have to
read the source code to verify this.

*4: mostly *regular* built-ins that behave as if they were separate
programs; not to be confused with *special* built-ins, which can do things
to the shell's internal state.

*5: Even if the shell's prompt includes its current directory - which isn't
the default - it could be out of date by the time the user presses *enter*
on their next command.