mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-08 12:50:49 +02:00
remove the [ and ] prompt expansions from prompt strings that are not used with readline; fix some redisplay issues when readline does not start in column 0; fix memory leak in unquoted $@ expansion; fix readline redisplay issue after SIGWINCH shrinks the terminal size; fix issue with mapfile that can cause crashes if a callback unsets the array mapfile is using
This commit is contained in:
@@ -12938,3 +12938,58 @@ subst.c
|
||||
after they return by adding an unwind-protect function
|
||||
uw_restore_verbose()
|
||||
Report and patch from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
5/18
|
||||
----
|
||||
doc/bash.1,doc/bashref.texi
|
||||
- note that PS0 and PS4 are not fed to readline, so they shouldn't
|
||||
contain the \[ and \] prompt escapes
|
||||
|
||||
parse.y
|
||||
- decode_prompt_string: if we're decoding a prompt string (is_prompt == 1),
|
||||
ignore \[ and \] unless the prompt is PS1 or PS2.
|
||||
Report from Egmont Koblinger <egmont@gmail.com>
|
||||
|
||||
5/19
|
||||
----
|
||||
lib/readline/display.c
|
||||
- rl_redisplay: when deciding whether or not to reprint the prompt from
|
||||
column 0 because the cursor is before the last invisible character,
|
||||
use local_prompt_len to compute index into the buffer in a multibyte
|
||||
locale, since _rl_last_c_pos is a screen position. This still doesn't
|
||||
fix the eventual redisplay breakage if readline starts with the
|
||||
cursor somewhere other than column 0
|
||||
Fixes issue reported by Lennart Ackermans <lennart@ackermans.ch>
|
||||
|
||||
5/20
|
||||
----
|
||||
builtins/getopt.c
|
||||
examples/loadables/seq.c
|
||||
lib/sh/mbschr.c,lib/sh/utf8.c
|
||||
pathexp.c
|
||||
examples/loadables/seq.c
|
||||
- fixes for `const' and gcc 15
|
||||
Report and patch from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
5/21
|
||||
----
|
||||
subst.c
|
||||
- string_list_dollar_atstar: fix memory leak by calling dispose_words(l2)
|
||||
after the call to word_list_split(l2)
|
||||
Report from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
5/22
|
||||
----
|
||||
lib/readline/display.c
|
||||
- _rl_redisplay_after_sigwinch: call _rl_reset_prompt every time, so
|
||||
the local_prompt_invis_chars array gets updated along with the
|
||||
local_prompt_newlines array
|
||||
Report and fix from Félix Bouynot <felix.bouynot@setenforce.one>
|
||||
|
||||
5/25
|
||||
----
|
||||
builtins/mapfile.def
|
||||
- mapfile: the callback can leave the variable in an inconsistent
|
||||
state, or even unset it, so we use bind_array_variable to look it
|
||||
up again every time through the loop
|
||||
Report and patch from Philippe Grégoire <git@pgregoire.xyz>
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/* getopt.c - getopt for Bash. Used by the getopt builtin. */
|
||||
|
||||
/* Copyright (C) 1993-2009,2022 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2009,2022,2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -113,7 +113,8 @@ int sh_badopt = 0;
|
||||
int
|
||||
sh_getopt (int argc, char *const *argv, const char *optstring)
|
||||
{
|
||||
char c, *temp;
|
||||
char c;
|
||||
const char *temp;
|
||||
|
||||
sh_optarg = 0;
|
||||
|
||||
|
||||
@@ -153,9 +153,7 @@ mapfile (int fd, long line_count_goal, long origin, long nskip, long callback_qu
|
||||
line_length = 0;
|
||||
unbuffered_read = 0;
|
||||
|
||||
/* The following check should be done before reading any lines. Doing it
|
||||
here allows us to call bind_array_element instead of bind_array_variable
|
||||
and skip the variable lookup on every call. */
|
||||
/* The following check should be done before reading any lines. */
|
||||
entry = builtin_find_indexed_array (array_name, flags & MAPF_CLEARARRAY);
|
||||
if (entry == 0)
|
||||
return EXECUTION_FAILURE;
|
||||
@@ -201,8 +199,13 @@ mapfile (int fd, long line_count_goal, long origin, long nskip, long callback_qu
|
||||
run_callback (callback, array_index, line);
|
||||
}
|
||||
|
||||
/* XXX - bad things can happen if the callback modifies ENTRY, e.g.,
|
||||
unsetting it or changing it to a non-indexed-array type. */
|
||||
/* Bad things can happen if the callback modifies ENTRY, e.g.,
|
||||
unsetting it or changing it to a non-indexed-array type, so we
|
||||
look it up again every time we need to assign something */
|
||||
entry = bind_array_variable (array_name, array_index, line, 0);
|
||||
if (entry == 0 || ASSIGN_DISALLOWED (entry, 0))
|
||||
return EXECUTION_FAILURE;
|
||||
|
||||
bind_array_element (entry, array_index, line, 0);
|
||||
|
||||
/* Have we exceeded # of lines to store? */
|
||||
|
||||
+11
-5
@@ -5,7 +5,7 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Wed May 6 16:08:33 EDT 2026
|
||||
.\" Last Change: Mon May 18 11:35:35 EDT 2026
|
||||
.\"
|
||||
.\" For bash_builtins, strip all but "SHELL BUILTIN COMMANDS" section
|
||||
.\" For rbash, strip all but "RESTRICTED SHELL" section
|
||||
@@ -22,7 +22,7 @@
|
||||
.ds zX \" empty
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2026 May 6" "GNU Bash 5.3"
|
||||
.TH BASH 1 "2026 May 18" "GNU Bash 5.3"
|
||||
.\"
|
||||
.ie \n(.g \{\
|
||||
.ds ' \(aq
|
||||
@@ -4328,7 +4328,8 @@ is invalid,
|
||||
.B bash
|
||||
prints a message to standard error indicating failure,
|
||||
does not perform the substitution,
|
||||
and does not execute the command associated with the expansion.
|
||||
and does not
|
||||
continue to execute the command in which the error occurs.
|
||||
.SS Process Substitution
|
||||
\fIProcess substitution\fP allows a process's input or output to be
|
||||
referred to using a filename.
|
||||
@@ -4336,7 +4337,9 @@ It takes the form of
|
||||
\fB<(\fP\fIlist\^\fP\fB)\fP
|
||||
or
|
||||
\fB>(\fP\fIlist\^\fP\fB)\fP.
|
||||
The process \fIlist\fP is run asynchronously, and its input or output
|
||||
The process \fIlist\fP,
|
||||
as long as it is not a null command without redirections,
|
||||
is run asynchronously, and its input or output
|
||||
appears as a filename.
|
||||
This filename is
|
||||
passed as an argument to the current command as the result of the
|
||||
@@ -6628,9 +6631,12 @@ A backslash.
|
||||
.B \e[
|
||||
Begin a sequence of non-printing characters, which could be used to
|
||||
embed a terminal control sequence into the prompt.
|
||||
This escape is only useful when the prompt will be supplied to
|
||||
\fBreadline\fP, so it shouldn't be used in \fBPS0\fP or \fBPS4\fP.
|
||||
.TP
|
||||
.B \e]
|
||||
End a sequence of non-printing characters.
|
||||
End a sequence of non-printing characters begun with
|
||||
.BR \e[ .
|
||||
.PD
|
||||
.RE
|
||||
.PP
|
||||
|
||||
+9
-3
@@ -2997,7 +2997,8 @@ The evaluation is performed according to the rules listed below
|
||||
If the expression is invalid, Bash prints a message indicating
|
||||
failure to the standard error,
|
||||
does not perform the substitution,
|
||||
and does not execute the command associated with the expansion.
|
||||
and does not
|
||||
continue to execute the command in which the error occurs.
|
||||
|
||||
@node Process Substitution
|
||||
@subsection Process Substitution
|
||||
@@ -3015,7 +3016,9 @@ or
|
||||
>(@var{list})
|
||||
@end example
|
||||
@noindent
|
||||
The process @var{list} is run asynchronously, and its input or output
|
||||
The process @var{list},
|
||||
as long as it is not a null command without redirections,
|
||||
is run asynchronously, and its input or output
|
||||
appears as a filename.
|
||||
This filename is
|
||||
passed as an argument to the current command as the result of the
|
||||
@@ -9154,8 +9157,11 @@ A backslash.
|
||||
Begin a sequence of non-printing characters.
|
||||
This could be used to
|
||||
embed a terminal control sequence into the prompt.
|
||||
This escape is only useful when the prompt will be supplied to
|
||||
Readline, so it shouldn't be used in @env{PS0} or @env{PS4}.
|
||||
|
||||
@item \]
|
||||
End a sequence of non-printing characters.
|
||||
End a sequence of non-printing characters begun with @samp{\[}
|
||||
@end table
|
||||
|
||||
The command number and the history number are usually different:
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2026 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Wed May 6 16:08:14 EDT 2026
|
||||
@set LASTCHANGE Mon May 18 11:35:01 EDT 2026
|
||||
|
||||
@set EDITION 5.3
|
||||
@set VERSION 5.3
|
||||
|
||||
@set UPDATED 6 May 2026
|
||||
@set UPDATED 18 May 2026
|
||||
@set UPDATED-MONTH May 2026
|
||||
|
||||
@@ -615,6 +615,8 @@ char *cut_doc[] = {
|
||||
"processes to successive elements of ARRAY, beginning at 0. The",
|
||||
"strings cut assigns to ARRAY are identical to the strings it would",
|
||||
"write to the standard output if -a were not supplied.",
|
||||
"",
|
||||
"-s stops printing of lines not containing delimiters. -n is ignored.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* seq - print sequence of numbers to standard output.
|
||||
Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
Copyright (C) 2018-2026 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -171,7 +171,7 @@ static int
|
||||
getprec (const char *numbuf)
|
||||
{
|
||||
int p;
|
||||
char *dp;
|
||||
const char *dp;
|
||||
|
||||
if (dp = strchr (numbuf, decimal_point))
|
||||
dp++; /* skip over decimal point */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* display.c -- readline redisplay facility. */
|
||||
|
||||
/* Copyright (C) 1987-2025 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -1497,7 +1497,6 @@ rl_redisplay (void)
|
||||
the characters from the current cursor position. But we
|
||||
only need to reprint it if the cursor is before the last
|
||||
invisible character in the prompt string. */
|
||||
/* XXX - why not use local_prompt_len? */
|
||||
nleft = prompt_visible_length + wrap_offset;
|
||||
if (cursor_linenum == prompt_last_screen_line)
|
||||
{
|
||||
@@ -1509,11 +1508,7 @@ rl_redisplay (void)
|
||||
on the current screen line begins in the buffer. It is a
|
||||
buffer position, an index into curline
|
||||
(local_prompt + pmt_offset) */
|
||||
cursor_bufpos = pmt_offset;
|
||||
if (mb_cur_max == 1 || rl_byte_oriented)
|
||||
cursor_bufpos += _rl_last_c_pos;
|
||||
else
|
||||
cursor_bufpos += _rl_last_c_pos + curline_invchars;
|
||||
cursor_bufpos = pmt_offset + local_prompt_len;
|
||||
|
||||
if (local_prompt && local_prompt_invis_chars[cursor_linenum] &&
|
||||
_rl_last_c_pos > 0 &&
|
||||
@@ -3525,8 +3520,9 @@ _rl_redisplay_after_sigwinch (void)
|
||||
else
|
||||
rl_crlf ();
|
||||
|
||||
if (_rl_screenwidth < prompt_visible_length)
|
||||
_rl_reset_prompt (); /* update local_prompt_newlines array */
|
||||
/* Let expand_prompt() update local_prompt_newlines and local_prompt_invis_chars
|
||||
arrays */
|
||||
_rl_reset_prompt ();
|
||||
|
||||
/* Redraw only the last line of a multi-line prompt. */
|
||||
t = strrchr (rl_display_prompt, '\n');
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* mbschr.c - strchr(3) that handles multibyte characters. */
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002-2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -81,5 +81,5 @@ mbschr (const char *s, int c)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return (strchr (s, c));
|
||||
return ((char *)strchr (s, c));
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* utf8.c - UTF-8 character handling functions */
|
||||
|
||||
/* Copyright (C) 2018, 2022 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2018, 2022, 2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -35,7 +35,7 @@ extern int locale_utf8locale;
|
||||
char *
|
||||
utf8_mbschr (const char *s, int c)
|
||||
{
|
||||
return strchr (s, c); /* for now */
|
||||
return (char *)strchr (s, c); /* for now */
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -6632,7 +6632,7 @@ decode_prompt_string (char *string, int is_prompt)
|
||||
#if defined (READLINE)
|
||||
case '[':
|
||||
case ']':
|
||||
if (no_line_editing)
|
||||
if (no_line_editing || (is_prompt && decoding_prompt != ps1_prompt && decoding_prompt != ps2_prompt))
|
||||
{
|
||||
string++;
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pathexp.c -- The shell interface to the globbing library. */
|
||||
|
||||
/* Copyright (C) 1995-2024 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995-2024,2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -525,7 +525,7 @@ static int
|
||||
glob_name_is_acceptable (const char *name)
|
||||
{
|
||||
struct ign *p;
|
||||
char *n;
|
||||
const char *n;
|
||||
int flags;
|
||||
|
||||
/* . and .. are never matched. We extend this to the terminal component of a
|
||||
|
||||
@@ -3167,6 +3167,8 @@ string_list_dollar_atstar (WORD_LIST *list, int quoted, int flags)
|
||||
don't want here. */
|
||||
l = word_list_split (l2); /* pre-split, preserving empty arguments */
|
||||
|
||||
dispose_words (l2);
|
||||
|
||||
/* We want to turn words that are QUOTED_NULL with W_HASQUOTEDNULL set in
|
||||
the word flags back into "" but leave every other $'\177' alone. */
|
||||
for (l2 = l; l2; l2 = l2->next)
|
||||
@@ -3183,7 +3185,6 @@ string_list_dollar_atstar (WORD_LIST *list, int quoted, int flags)
|
||||
free (sep);
|
||||
#endif
|
||||
|
||||
dispose_words (l2);
|
||||
dispose_words (l);
|
||||
|
||||
return ret;
|
||||
@@ -8905,6 +8906,23 @@ get_var_and_type (char *varname, char *value, array_eltstate_t *estatep, int quo
|
||||
*valp = temp ? savestring (temp) : temp;
|
||||
}
|
||||
}
|
||||
#if 0 /* TAG:bash-5.4 2026/05/11 YourLi@outlook.com */
|
||||
/* For ksh93 compatibility, ${!ref} where ref is a non-special, nameref
|
||||
variable, should expand to the value of ref, without resolving any
|
||||
nameref chain. Previous versions treated an array variable without a
|
||||
subscript the same as ref[0] (next clause). */
|
||||
else if (shell_compatibility_level > 53 &&
|
||||
want_indir && value && vtype == VT_VARIABLE &&
|
||||
SPECIAL_VAR (varname, 1) == 0 &&
|
||||
(v = find_variable_noref (varname + 1)) &&
|
||||
nameref_p (v))
|
||||
{
|
||||
/* This is for compatibility with ksh93. */
|
||||
vtype = VT_VARIABLE;
|
||||
*varp = v;
|
||||
*valp = savestring (value);
|
||||
}
|
||||
#endif
|
||||
else if ((v = find_variable (vname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
|
||||
{
|
||||
vtype = VT_ARRAYMEMBER;
|
||||
|
||||
Reference in New Issue
Block a user