declare builtin changes to reject -i when used with -n; readline changes to make control characters visible in search strings; readline signal handling changes to avoid data corruption and UAF; documentation updates for more consistent quoting

This commit is contained in:
Chet Ramey
2025-09-04 12:29:57 -04:00
parent ab17ddb7af
commit a451bfc3f5
46 changed files with 36912 additions and 1499 deletions
+2 -2
View File
@@ -826,10 +826,10 @@ rl_redisplay (void)
if (_rl_echoing_p == 0)
return;
RL_SETSTATE (RL_STATE_REDISPLAYING);
/* Block keyboard interrupts because this function manipulates global
data structures. */
_rl_block_sigint ();
RL_SETSTATE (RL_STATE_REDISPLAYING);
cur_face = FACE_NORMAL;
/* Can turn this into an array for multiple highlighted objects in addition
@@ -1708,8 +1708,8 @@ rl_redisplay (void)
_rl_quick_redisplay = 0;
}
RL_UNSETSTATE (RL_STATE_REDISPLAYING);
_rl_release_sigint ();
RL_UNSETSTATE (RL_STATE_REDISPLAYING);
}
static void
+2 -2
View File
@@ -696,7 +696,7 @@ This determines the current keymap and key bindings.
* Terminal Management:: Functions to manage terminal settings.
* Utility Functions:: Generally useful functions and hooks.
* Miscellaneous Functions:: Functions that don't fall into any category.
* Alternate Interface:: Using Readline in a `callback' fashion.
* Alternate Interface:: Using Readline in a ``callback'' fashion.
* A Readline Example:: An example Readline function.
* Alternate Interface Example:: An example program using the alternate interface.
@end menu
@@ -1545,7 +1545,7 @@ Some applications need to interleave keyboard I/O with file, device,
or window system I/O, typically by using a main loop to @code{select()}
on various file descriptors.
To accommodate this use case, Readline can
also be invoked as a `callback' function from an event loop.
also be invoked as a ``callback'' function from an event loop.
There are functions available to make this easy.
@deftypefun void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *line_handler)
+39 -18
View File
@@ -85,11 +85,11 @@ Line editing can be enabled at any time using the @option{-o emacs} or
The following paragraphs use Emacs style to
describe the notation used to represent keystrokes.
The text @kbd{C-k} is read as `Control-K' and describes the character
The text @kbd{C-k} is read as ``Control-K'' and describes the character
produced when the @key{k} key is pressed while the Control key
is depressed.
The text @kbd{M-k} is read as `Meta-K' and describes the character
The text @kbd{M-k} is read as ``Meta-K'' and describes the character
produced when the Meta key (if you have one) is depressed, and the @key{k}
key is pressed (a @dfn{meta character}), then both are released.
The Meta key is labeled @key{ALT} or @key{Option} on many keyboards.
@@ -120,7 +120,7 @@ you can make @kbd{M-key} key bindings you specify
(see @code{Key Bindings} in @ref{Readline Init File Syntax})
do the same thing by setting the @code{force-meta-prefix} variable.
The text @kbd{M-C-k} is read as `Meta-Control-k' and describes the
The text @kbd{M-C-k} is read as ``Meta-Control-k'' and describes the
character produced by metafying @kbd{C-k}.
In addition, several keys have their own names.
@@ -178,10 +178,10 @@ and then correct your mistake.
Afterwards, you can move the cursor to the right with @kbd{C-f}.
When you add text in the middle of a line, you will notice that characters
to the right of the cursor are `pushed over' to make room for the text
to the right of the cursor are ``pushed over'' to make room for the text
that you have inserted.
Likewise, when you delete text behind the cursor,
characters to the right of the cursor are `pulled back' to fill in the
characters to the right of the cursor are ``pulled back'' to fill in the
blank space created by the removal of the text.
These are the bare
essentials for editing the text of an input line:
@@ -244,9 +244,9 @@ operate on characters while meta keystrokes operate on words.
@dfn{Killing} text means to delete the text from the line, but to save
it away for later use, usually by @dfn{yanking} (re-inserting)
it back into the line.
(`Cut' and `paste' are more recent jargon for `kill' and `yank'.)
(``Cut'' and ``paste'' are more recent jargon for ``kill'' and ``yank''.)
If the description for a command says that it `kills' text, then you can
If the description for a command says that it ``kills'' text, then you can
be sure that you can get the text back in a different (or the same)
place later.
@@ -307,9 +307,10 @@ act in a backward direction.
For example, to kill text back to the
start of the line, you might type @samp{M-- C-k}.
The general way to pass numeric arguments to a command is to type meta
digits before the command.
If the first `digit' typed is a minus
The general way to pass numeric arguments to a command is to type
the Meta key and then digits (``meta digits'')
before the command.
If the first ``digit'' typed is a minus
sign (@samp{-}), then the sign of the argument will be negative.
Once you have typed one meta digit to get the argument started, you can
type the remainder of the digits, and then the command.
@@ -1420,11 +1421,11 @@ If this line is a modified history line, then restore the history line
to its original state.
@item previous-history (C-p)
Move `back' through the history list, fetching the previous command.
Move ``back'' through the history list, fetching the previous command.
This may also be bound to the up arrow key on some keyboards.
@item next-history (C-n)
Move `forward' through the history list, fetching the next command.
Move ``forward'' through the history list, fetching the next command.
This may also be bound to the down arrow key on some keyboards.
@item beginning-of-history (M-<)
@@ -1435,25 +1436,26 @@ Move to the end of the input history, i.e., the line currently
being entered.
@item reverse-search-history (C-r)
Search backward starting at the current line and moving `up' through
Search backward starting at the current line and moving ``up'' through
the history as necessary.
This is an incremental search.
This command sets the region to the matched text and activates the region.
@item forward-search-history (C-s)
Search forward starting at the current line and moving `down' through
Search forward starting at the current line and moving ``down'' through
the history as necessary.
This is an incremental search.
This command sets the region to the matched text and activates the region.
@item non-incremental-reverse-search-history (M-p)
Search backward starting at the current line and moving `up'
Search backward starting at the current line and moving ``up''
through the history as necessary using a non-incremental search
for a string supplied by the user.
The search string may match anywhere in a history line.
@item non-incremental-forward-search-history (M-n)
Search forward starting at the current line and moving `down'
Search forward starting at the current line and moving ``down''
through the history as necessary using a non-incremental search
for a string supplied by the user.
The search string may match anywhere in a history line.
@@ -2135,8 +2137,8 @@ when in @code{vi} mode and to vi-editing-mode in @code{emacs} mode).
The Readline default is @code{emacs} mode.
When you enter a line in @code{vi} mode, you are already placed in
`insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC}
switches you into `command' mode, where you can edit the text of the
``insertion'' mode, as if you had typed an @samp{i}. Pressing @key{ESC}
switches you into ``command'' mode, where you can edit the text of the
line with the standard @code{vi} movement keys, move to previous
history lines with @samp{k} and subsequent lines with @samp{j}, and
so forth.
@@ -2259,6 +2261,25 @@ the standard output.
Backslash will escape a newline, if necessary.
These are added to the set of possible completions.
External commands that are invoked to generate completions
("external completers")
receive the word preceding the completion word as an argument,
as described above.
This provides context that is sometimes useful, but may include
information that is considered sensitive or part of a word expansion
that will not appear in the command line after expansion.
That word may be visible in process listings or in audit logs.
This may be a concern to users and completion specification authors
if there is sensitive information on the command line before
expansion, since completion takes place before words are expanded.
If this is an issue, completion authors should use functions as
wrappers around external commands and pass context information to the
external command in a different way.
External completers can infer context from the @var{COMP_LINE}
and @var{COMP_POINT} environment variables, but they need to ensure
they break words in the same way Readline does, using the
@var{COMP_WORDBREAKS} variable.
After generating all of the possible completions,
Bash applies any filter
specified with the @option{-X} option to the completions in the list.
+3 -3
View File
@@ -5,7 +5,7 @@ Copyright (C) 1988-2025 Free Software Foundation, Inc.
@set EDITION 8.3
@set VERSION 8.3
@set UPDATED 15 July 2025
@set UPDATED-MONTH July 2025
@set UPDATED 25 August 2025
@set UPDATED-MONTH August 2025
@set LASTCHANGE Tue Jul 15 10:18:40 EDT 2025
@set LASTCHANGE Mon Aug 25 11:33:46 EDT 2025
+9 -9
View File
@@ -825,14 +825,14 @@ rl_read_key (void)
{
if (rl_get_char (&c) == 0)
c = (*rl_getc_function) (rl_instream);
if (_rl_caught_signal)
{
fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: c = %d _rl_caught_signal = %d\r\n", c, _rl_caught_signal);
if (c > 0)
rl_stuff_char (c);
c = -1;
RL_CHECK_SIGNALS ();
}
/* This can happen if rl_getc_function != rl_getc */
if (_rl_caught_signal)
{
if (c > 0)
rl_stuff_char (c);
c = -1;
RL_CHECK_SIGNALS ();
}
}
}
@@ -1005,7 +1005,7 @@ postproc_signal:
(*rl_signal_event_hook) ();
/* If the application's SIGINT handler returns, make sure we abort out of
searches and numeric arguments because we've freed necessary state. */
if (osig == SIGINT && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
if (osig == SIGINT && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG|RL_STATE_MOREINPUT)))
/* just these cases for now */
_rl_abort_internal ();
}
+12 -4
View File
@@ -153,10 +153,11 @@ rl_display_search (char *search_string, int flags, int where)
{
char *message;
size_t msglen, searchlen;
unsigned char c;
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = (char *)xmalloc (searchlen + 64);
message = (char *)xmalloc (searchlen * 2 + 64);
msglen = 0;
#if defined (NOTDEF)
@@ -186,8 +187,15 @@ rl_display_search (char *search_string, int flags, int where)
if (search_string && *search_string)
{
strcpy (message + msglen, search_string);
msglen += searchlen;
for ( ; c = *search_string; search_string++)
{
if (CTRL_CHAR (c) || c == RUBOUT)
{
message[msglen++] = '^';
c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
}
message[msglen++] = c;
}
}
else
_rl_optimize_redisplay ();
@@ -319,7 +327,7 @@ _rl_search_getchar (_rl_search_cxt *cxt)
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = cxt->lastc = rl_read_key ();
c = cxt->lastc = rl_read_key (); /* XXX */
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
+7
View File
@@ -672,12 +672,19 @@ _rl_block_sigint (void)
void
_rl_release_sigint (void)
{
int osig, ostate;
if (sigint_blocked == 0)
return;
sigint_blocked = 0;
osig = _rl_caught_signal;
ostate = rl_readline_state;
if (RL_ISSTATE (RL_STATE_SIGHANDLER) == 0)
RL_CHECK_SIGNALS ();
/* These are basically all the places that call rl_message() */
if (osig == SIGINT && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG|RL_STATE_MOREINPUT|RL_STATE_READSTR)))
_rl_abort_internal ();
}
int
+2 -2
View File
@@ -2026,12 +2026,12 @@ _rl_readstr_init (int pchar, int flags)
rl_end = rl_point = 0;
p = _rl_make_prompt_for_search (pchar ? pchar : '@');
RL_SETSTATE (RL_STATE_READSTR);
cxt->flags |= READSTR_FREEPMT;
rl_message ("%s", p);
xfree (p);
RL_SETSTATE (RL_STATE_READSTR);
_rl_rscxt = cxt;
return cxt;