Bash-5.2 patch 13

2022-12-14 Thread Chet Ramey
 BASH PATCH REPORT
 =

Bash-Release:   5.2
Patch-ID:   bash52-013

Bug-Reported-by:Ralf Oehler 
Bug-Reference-ID:   <20221120140252.2fc6489b@bilbo>
Bug-Reference-URL:  
https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00082.html

Bug-Description:

Bash can leak memory when referencing a non-existent associative array
element.

Patch (apply with `patch -p0'):

*** ../bash-5.2-patched/subst.c 2022-11-05 17:27:48.0 -0400
--- subst.c 2022-11-21 14:42:59.0 -0500
***
*** 7498,7503 
: quote_escapes (temp);
  rflags |= W_ARRAYIND;
- if (estatep)
-   *estatep = es;  /* structure copy */
}
/* Note that array[*] and array[@] expanded to a quoted null string by
--- 7508,7511 
***
*** 7508,7512 
rflags |= W_HASQUOTEDNULL;
  
!   if (estatep == 0)
flush_eltstate (&es);
  }
--- 7516,7522 
rflags |= W_HASQUOTEDNULL;
  
!   if (estatep)
!   *estatep = es;  /* structure copy */
!   else
flush_eltstate (&es);
  }
*** ../bash-5.2/patchlevel.h2020-06-22 14:51:03.0 -0400
--- patchlevel.h2020-10-01 11:01:28.0 -0400
***
*** 26,30 
 looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 12
  
  #endif /* _PATCHLEVEL_H_ */
--- 26,30 
 looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 13
  
  #endif /* _PATCHLEVEL_H_ */

-- 
``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/



Bash-5.2 patch 14

2022-12-14 Thread Chet Ramey
 BASH PATCH REPORT
 =

Bash-Release:   5.2
Patch-ID:   bash52-014

Bug-Reported-by:Andreas Schwab 
Bug-Reference-ID:   
Bug-Reference-URL:  
https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00076.html

Bug-Description:

Bash defers processing additional terminating signals when running the
EXIT trap while exiting due to a terminating signal. This patch allows the
new terminating signal to kill the shell immediately.

Patch (apply with `patch -p0'):

*** ../bash-5.2-patched/execute_cmd.c   2022-11-23 17:09:18.0 -0500
--- execute_cmd.c   2022-11-28 10:36:08.0 -0500
***
*** 3625,3628 
--- 3649,3653 
  
  dispose_words (es);
+ QUIT;
  
  if (match)
*** ../bash-5.2-patched/sig.c   2021-11-04 14:15:31.0 -0400
--- sig.c   2022-12-06 09:45:11.0 -0500
***
*** 95,98 
--- 95,99 
  
  static void initialize_shell_signals PARAMS((void));
+ static void kill_shell PARAMS((int));
  
  void
***
*** 487,490 
--- 495,500 
  }
  
+ static int handling_termsig = 0;
+ 
  sighandler
  termsig_sighandler (sig)
***
*** 533,536 
--- 543,554 
  terminate_immediately = 1;
  
+   /* If we are currently handling a terminating signal, we have a couple of
+  choices here. We can ignore this second terminating signal and let the
+  shell exit from the first one, or we can exit immediately by killing
+  the shell with this signal. This code implements the latter; to implement
+  the former, replace the kill_shell(sig) with return. */
+   if (handling_termsig)
+ kill_shell (sig); /* just short-circuit now */
+ 
terminating_signal = sig;
  
***
*** 565,572 
   int sig;
  {
-   static int handling_termsig = 0;
-   int i, core;
-   sigset_t mask;
- 
/* Simple semaphore to keep this function from being executed multiple
   times.  Since we no longer are running as a signal handler, we don't
--- 585,588 
***
*** 574,578 
if (handling_termsig)
  return;
!   handling_termsig = 1;
terminating_signal = 0; /* keep macro from re-testing true. */
  
--- 590,595 
if (handling_termsig)
  return;
! 
!   handling_termsig = terminating_signal;  /* for termsig_sighandler */
terminating_signal = 0; /* keep macro from re-testing true. */
  
***
*** 614,617 
--- 631,644 
run_exit_trap ();   /* XXX - run exit trap possibly in signal context? */
  
+   kill_shell (sig);
+ }
+ 
+ static void
+ kill_shell (sig)
+  int sig;
+ {
+   int i, core;
+   sigset_t mask;
+ 
/* We don't change the set of blocked signals. If a user starts the shell
   with a terminating signal blocked, we won't get here (and if by some
*** ../bash-5.2/patchlevel.h2020-06-22 14:51:03.0 -0400
--- patchlevel.h2020-10-01 11:01:28.0 -0400
***
*** 26,30 
 looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 13
  
  #endif /* _PATCHLEVEL_H_ */
--- 26,30 
 looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 14
  
  #endif /* _PATCHLEVEL_H_ */

-- 
``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/



Re: Nested expansion in heredoc fails

2022-12-14 Thread Chet Ramey

On 12/13/22 12:42 PM, Norbert Lange wrote:


Bash Version: 5.2
Patch Level: 2
Release Status: release

Description:
Parameter expansion within heredocs fails.

The code below works with other shells aswell as bash 5.1


Thanks for the report. It's an off-by-one error that is specific to command
substitution within parameter expansion in a here-document line. Here's a
patch.

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/
*** ../bash-5.2-patched/subst.c 2022-12-13 12:08:58.0 -0500
--- subst.c 2022-12-14 09:09:53.0 -0500
***
*** 1694,1698 
  CHECK_STRING_OVERRUN (i, si, slen, c);
  
! tlen = si - i - 1;
  RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 
64);
  result[result_index++] = c;
--- 1699,1703 
  CHECK_STRING_OVERRUN (i, si, slen, c);
  
! tlen = si - i - 2;
  RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 
64);
  result[result_index++] = c;
***
*** 1714,1718 
  CHECK_STRING_OVERRUN (i, si, slen, c);
  
! tlen = si - i - 1;
  RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 
64);
  result[result_index++] = c;
--- 1719,1723 
  CHECK_STRING_OVERRUN (i, si, slen, c);
  
! tlen = si - i - 2;
  RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 
64);
  result[result_index++] = c;


Re: Nested expansion in heredoc fails

2022-12-14 Thread wang yuhang
Hello 

In bash-5.2, There is one modification: fix to expand $'...' and 
$"..." in certain word expansions while expanding lines of here-document data


This modification has been changed when dealing with '$(', It seems 
to have missed the right bracket. Maybe we should add this bracket.


I hope this patch can fix your problem

fix.patch
Description: Binary data


Bash-5.2 patch 15

2022-12-14 Thread Chet Ramey
 BASH PATCH REPORT
 =

Bash-Release:   5.2
Patch-ID:   bash52-015

Bug-Reported-by:Frode Nordahl 
Bug-Reference-ID:   <20221119070714.351759-1-frode.nord...@canonical.com>
Bug-Reference-URL:  
https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00078.html

Bug-Description:

There are several cases where bash is too aggressive when optimizing out forks
in subshells. For example, `eval' and traps should never be optimized.

Patch (apply with `patch -p0'):

*** ../bash-5.2-patched/builtins/common.h   2022-11-23 17:09:18.0 
-0500
--- builtins/common.h   2022-11-19 18:03:59.0 -0500
***
*** 52,55 
--- 52,56 
  #define SEVAL_ONECMD  0x100   /* only allow a single command */
  #define SEVAL_NOHISTEXP   0x200   /* inhibit history expansion */
+ #define SEVAL_NOOPTIMIZE 0x400/* don't try to set 
optimization flags */
  
  /* Flags for describe_command, shared between type.def and command.def */
*** ../bash-5.2-patched/builtins/evalstring.c   2022-11-05 17:27:44.0 
-0400
--- builtins/evalstring.c   2022-11-19 18:23:21.0 -0500
***
*** 133,138 
(command->value.Connection->connector == AND_AND || 
command->value.Connection->connector == OR_OR || 
command->value.Connection->connector == ';') &&
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
!   ((startup_state == 2 && should_suppress_fork 
(command->value.Connection->second)) ||
!((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork 
(command->value.Connection->second, 0
  {
command->value.Connection->second->flags |= CMD_NO_FORK;
--- 133,138 
(command->value.Connection->connector == AND_AND || 
command->value.Connection->connector == OR_OR || 
command->value.Connection->connector == ';') &&
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
!   (should_suppress_fork (command->value.Connection->second) ||
!   ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork 
(command->value.Connection->second, 0
  {
command->value.Connection->second->flags |= CMD_NO_FORK;
***
*** 291,294 
--- 291,295 
(flags & SEVAL_RESETLINE) -> reset line_number to 1
(flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1
+   (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags
  */
  
***
*** 503,507 
 series of connection commands is
 command->value.Connection->second. */
! else if (command->type == cm_connection && 
can_optimize_connection (command))
{
  command->value.Connection->second->flags |= 
CMD_TRY_OPTIMIZING;
--- 504,510 
 series of connection commands is
 command->value.Connection->second. */
! else if (command->type == cm_connection &&
!  (flags & SEVAL_NOOPTIMIZE) == 0 &&
!  can_optimize_connection (command))
{
  command->value.Connection->second->flags |= 
CMD_TRY_OPTIMIZING;
*** ../bash-5.2-patched/builtins/eval.def   2016-01-25 13:28:37.0 
-0500
--- builtins/eval.def   2022-11-19 18:04:25.0 -0500
***
*** 54,57 
list = loptend; /* skip over possible `--' */
  
!   return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : 
EXECUTION_SUCCESS);
  }
--- 54,57 
list = loptend; /* skip over possible `--' */
  
!   return (list ? evalstring (string_list (list), "eval", 
SEVAL_NOHIST|SEVAL_NOOPTIMIZE) : EXECUTION_SUCCESS);
  }
*** ../bash-5.2-patched/trap.c  2022-08-10 08:59:45.0 -0400
--- trap.c  2022-12-12 10:57:51.0 -0500
***
*** 305,308 
--- 305,309 
volatile int save_return_catch_flag, function_code;
procenv_t save_return_catch;
+   char *trap_command, *old_trap;
  #if defined (ARRAY_VARS)
ARRAY *ps;
***
*** 420,423 
--- 421,427 
  else
{
+ old_trap = trap_list[sig];
+ trap_command = savestring (old_trap);
+ 
  save_parser_state (&pstate);
  save_subst_varlist = subst_assign_varlist;
***
*** 442,446 
  
  if (function_code == 0)
!   x = parse_and_execute (savestring (trap_list[sig]), "trap", 
SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
  else
{
--- 446,451 
  
  if (function_code == 0)
!   /* XXX is x always last_command_exit_value? */
!   x = parse_and_execute (trap_command, "trap", 
SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
  else
{
***
*** 1003,1007 
{
  reset_parser ();
!  

Re: Nested expansion in heredoc fails

2022-12-14 Thread wang yuhang
On 12/13/22 12:42 PM, wang yuhang wrote:> This modification has 
been changed when dealing with '$(', It seems  > to have missed the 
right bracket. Maybe we should add this bracket.
It seems that there is something wrong with this patch, It's true that my brain 
is not very good late at night. Please ignore it

Re: bash crashes if TERM is unset and the Delete key is pressed twice

2022-12-14 Thread Chet Ramey

On 12/13/22 9:00 AM, Emanuele Torre wrote:

This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b .

If bash is started with the TERM variable unset or empty, it will
segfault and crash if you press the Delete key twice (it only happens
for the first prompt, and if you don't press anything before the two
Delete key presses).


I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all
using xterm.

--
``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/




Re: bash crashes if TERM is unset and the Delete key is pressed twice

2022-12-14 Thread Emanuele Torre
On Wed, Dec 14, 2022 at 12:31:39PM -0500, Chet Ramey wrote:
> On 12/13/22 9:00 AM, Emanuele Torre wrote:
> > This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b .
> > 
> > If bash is started with the TERM variable unset or empty, it will
> > segfault and crash if you press the Delete key twice (it only happens
> > for the first prompt, and if you don't press anything before the two
> > Delete key presses).
> 
> I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all
> using xterm.

I can reproduce it consistently on my computer.

I tried to figure out what is causing the issue using gdb on the commit
88d69b4fa224d93ef1d26b80229668397bb6496b .

It seems that, in readline_internal_charloop(), if the memcpy() at line
593 (introduced with that commit) is present:


 #if defined (HAVE_POSIX_SIGSETJMP)
   code = sigsetjmp (_rl_top_level, 0);
 #else
   code = setjmp (_rl_top_level);
 #endif

   if (code)
 {
   (*rl_redisplay_function) ();
   _rl_want_redisplay = 0;
+  memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));

   /* If we longjmped because of a timeout, handle it here. */
   if (RL_ISSTATE (RL_STATE_TIMEOUT))

Then the call to _rl_dispatch() on line 680, causes a segfault:

  lastc = c;
  r = _rl_dispatch ((unsigned char)c, _rl_keymap);

It is called with those `c' and `_rl_keymap' values

  (gdb) p c
  $1 = 27
  (gdb) p _rl_keymap
  $2 = (Keymap) 0x55c653164ae0 

Removing that memcpy() call prevents the segfault.

Between the memcpy() and _rl_dispatch() call, the program enters only in
the following `if' block:

  if (rl_pending_input == 0)
{
  /* Then initialize the argument and number of keys read. */
  _rl_reset_argument ();
  rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
}

I hope this helps.
 emanuele6



Re: bash crashes if TERM is unset and the Delete key is pressed twice

2022-12-14 Thread Chet Ramey

On 12/14/22 2:01 PM, Emanuele Torre wrote:

On Wed, Dec 14, 2022 at 12:31:39PM -0500, Chet Ramey wrote:

On 12/13/22 9:00 AM, Emanuele Torre wrote:

This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b .

If bash is started with the TERM variable unset or empty, it will
segfault and crash if you press the Delete key twice (it only happens
for the first prompt, and if you don't press anything before the two
Delete key presses).


I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all
using xterm.


I can reproduce it consistently on my computer.

I tried to figure out what is causing the issue using gdb on the commit
88d69b4fa224d93ef1d26b80229668397bb6496b .


Try this.

*** ../bash-20221202/lib/readline/readline.c	2022-12-06 09:48:50.0 
-0500

--- lib/readline/readline.c 2022-12-14 14:20:32.0 -0500
***
*** 591,595 
  (*rl_redisplay_function) ();
  _rl_want_redisplay = 0;
! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));

  /* If we longjmped because of a timeout, handle it here. */
--- 591,596 
  (*rl_redisplay_function) ();
  _rl_want_redisplay = 0;
! if (RL_ISSTATE (RL_STATE_CALLBACK))
!   memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));

  /* If we longjmped because of a timeout, handle it here. */


--
``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/




Re: bash crashes if TERM is unset and the Delete key is pressed twice

2022-12-14 Thread Emanuele Torre
On Wed, Dec 14, 2022 at 02:30:04PM -0500, Chet Ramey wrote:
> Try this.
> 
> *** ../bash-20221202/lib/readline/readline.c  2022-12-06 09:48:50.0
> -0500
> --- lib/readline/readline.c   2022-12-14 14:20:32.0 -0500
> ***
> *** 591,595 
> (*rl_redisplay_function) ();
> _rl_want_redisplay = 0;
> !   memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
> 
> /* If we longjmped because of a timeout, handle it here. */
> --- 591,596 
> (*rl_redisplay_function) ();
> _rl_want_redisplay = 0;
> !   if (RL_ISSTATE (RL_STATE_CALLBACK))
> ! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
> 
> /* If we longjmped because of a timeout, handle it here. */

Thank you. That seems to fix the issue.
 emanuele6



compgen stops processing backslashes after any call to bind

2022-12-14 Thread Fabien Orjollet

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fstack-protector-strong -Wformat 
-Werror=format-security -Wall
uname output: Linux debtest 6.0.0-5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 
6.0.10-2 (2022-12-01) x86_64 GNU/Linux

Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.2
Patch Level: 2
Release Status: release

Description:
compgen's behavior regarding backslash processing is altered by
any call to bind.
Therefore, file and directory names containing a backslash are
not completed once bind has been called.
Below is an example to reproduce the issue followed by its
output.
Thanks.

Repeat-By:
#!/usr/bin/env bash

[[ "$(find /tmp/ -maxdepth 1 -type d -name "Dir*")" ]] && exit 2
mkdir /tmp/Dir{\\A,B,\\C}
touch /tmp/Dir\\A/file\\A /tmp/DirB/fileB 
/tmp/Dir\\C/file\\C


set -o emacs

f_comp() {
   case "$1" in
  1) compgen -f "$2";;
  2) compgen -o dirnames -f "$2";;
   esac
}

for DF in "/tmp/Dir" "/tmp/Dir\\A" "/tmp/DirB" "/tmp/Dir\\" \
  "/tmp/Dir\\A/" "/tmp/DirB/" "/tmp/Dir\\C/" \
  "/tmp/Dir\\A/file"; do
   echo
   echo "$(( ++COUNT )) compgen1  $DF  before bind>>> $(f_comp 1 "$DF")"
   echo "$COUNT compgen2  $DF  before bind>>> $(f_comp 2 "$DF")"
done
echo; COUNT=0

bind -X

for DF in "/tmp/Dir" "/tmp/Dir\\A" "/tmp/DirB" "/tmp/Dir\\" \
  "/tmp/Dir\\A/" "/tmp/DirB/" "/tmp/Dir\\C/" \
  "/tmp/Dir\\A/file"; do
   echo
   echo "$(( ++COUNT )) compgen1  $DF  after bind>>> $(f_comp 1 "$DF")"
   echo "$COUNT compgen2  $DF  after bind>>> $(f_comp 2 "$DF")"
done

rm -rf /tmp/Dir\\*


### Output:
1 compgen1  /tmp/Dir  before bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B
1 compgen2  /tmp/Dir  before bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B

2 compgen1  /tmp/Dir\A  before bind>>> /tmp/Dir\A
2 compgen2  /tmp/Dir\A  before bind>>> /tmp/Dir\A

3 compgen1  /tmp/Dir\\B  before bind>>> /tmp/Dir\\B
3 compgen2  /tmp/Dir\\B  before bind>>> /tmp/Dir\\B

4 compgen1  /tmp/Dir\\\  before bind>>> /tmp/Dir\\\C
4 compgen2  /tmp/Dir\\\  before bind>>> /tmp/Dir\\\C

5 compgen1  /tmp/Dir\A/  before bind>>> /tmp/Dir\A/file\A
5 compgen2  /tmp/Dir\A/  before bind>>> /tmp/Dir\A/file\A

6 compgen1  /tmp/Dir\\B/  before bind>>> /tmp/Dir\\B/file\\B
6 compgen2  /tmp/Dir\\B/  before bind>>> /tmp/Dir\\B/file\\B

7 compgen1  /tmp/Dir\\\C/  before bind>>> /tmp/Dir\\\C/file\\\C
7 compgen2  /tmp/Dir\\\C/  before bind>>> /tmp/Dir\\\C/file\\\C

8 compgen1  /tmp/Dir\A/file  before bind>>> /tmp/Dir\A/file\A
8 compgen2  /tmp/Dir\A/file  before bind>>> /tmp/Dir\A/file\A


1 compgen1  /tmp/Dir  after bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B
1 compgen2  /tmp/Dir  after bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B

2 compgen1  /tmp/Dir\A  after bind>>>
2 compgen2  /tmp/Dir\A  after bind>>> /tmp/Dir\A

3 compgen1  /tmp/Dir\\B  after bind>>>
3 compgen2  /tmp/Dir\\B  after bind>>> /tmp/Dir\\B

4 compgen1  /tmp/Dir\\\  after bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B
4 compgen2  /tmp/Dir\\\  after bind>>> /tmp/Dir\A
/tmp/Dir\\\C
/tmp/Dir\\B

5 compgen1  /tmp/Dir\A/  after bind>>>
5 compgen2  /tmp/Dir\A/  after bind>>>

6 compgen1  /tmp/Dir\\B/  after bind>>>
6 compgen2  /tmp/Dir\\B/  after bind>>>

7 compgen1  /tmp/Dir\\\C/  after bind>>>
7 compgen2  /tmp/Dir\\\C/  after bind>>>

8 compgen1  /tmp/Dir\A/file  after bind>>>
8 compgen2  /tmp/Dir\A/file  after bind>>>