mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-11-11 00:53:52 +01:00
fix potential crash with invalid readline key binding command; fix crash caused by signal cleanup after using ^G to abort out of listing possible completions
This commit is contained in:
1 parent
a4a9dbc1b6
commit
f7043f647e
6 files changed
+63
-8
No files matched your search
@@ -13524,3 +13524,27 @@ redir.c
|
||||
with zreadc/zreadcintr/zreadn and invalidate the buffered data
|
||||
if so
|
||||
Report from Edgar MAGDELAINE <edgarmagdelaine@hotmail.fr>
|
||||
|
||||
11/4
|
||||
----
|
||||
lib/readline/bind.c
|
||||
- rl_generic_bind: make sure to cast prevkey to unsigned char because
|
||||
we use it as an index into a keymap
|
||||
Report and fix from Can Ozkan <can.ozkan@esat.kuleuven.be>
|
||||
|
||||
11/6
|
||||
----
|
||||
lib/readline/complete.c
|
||||
- _rl_abort_completion: new function, fakes a signal to clean up the
|
||||
saved match list state, then calls _rl_abort_internal
|
||||
- get_y_or_n: if we read ^G or get a read error, return -1 and let
|
||||
the caller handle it instead of calling _rl_abort_internal()
|
||||
- _rl_internal_pager, display_matches: if get_y_or_n returns -1, call
|
||||
_rl_abort_completion to clean up the completion state and longjmp
|
||||
back to reading input
|
||||
Report from Sergio Herreros <sergioherrerosp@gmail.com>
|
||||
|
||||
lib/readline/util.c,lib/readline/rlprivate.h
|
||||
- _rl_abort_internal: now a void function with noreturn attribute;
|
||||
changed callers to accommodate
|
||||
|
||||
@@ -87,4 +87,8 @@ extern void setup_history_ignore (const char *);
|
||||
|
||||
extern char *last_history_line (void);
|
||||
|
||||
#ifdef BASH_SYSLOG_HISTORY
|
||||
extern void bash_syslog_history (const char *);
|
||||
#endif
|
||||
|
||||
#endif /* _BASHHIST_H_ */
|
||||
+6
-1
@@ -410,7 +410,12 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
}
|
||||
|
||||
prevmap = map;
|
||||
prevkey = keys[0];
|
||||
prevkey = (unsigned char)keys[0];
|
||||
if (prevkey >= KEYMAP_SIZE)
|
||||
{
|
||||
xfree (keys);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bind keys, making new keymaps as necessary. */
|
||||
for (i = 0; i < keys_len; i++)
|
||||
|
||||
+25
-3
@@ -129,6 +129,7 @@ static int path_isdir (const char *);
|
||||
static char *rl_quote_filename (char *, int, char *);
|
||||
|
||||
static void _rl_complete_sigcleanup (int, void *);
|
||||
static void _rl_abort_completion (void) __attribute__((noreturn));
|
||||
|
||||
static void set_completion_defaults (int);
|
||||
static int get_y_or_n (int);
|
||||
@@ -540,6 +541,19 @@ _rl_complete_sigcleanup (int sig, void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_rl_abort_completion ()
|
||||
{
|
||||
if (_rl_sigcleanup && _rl_sigcleanup == _rl_complete_sigcleanup)
|
||||
{
|
||||
_rl_sigcleanup (SIGINT, _rl_sigcleanarg);
|
||||
_rl_sigcleanup = 0;
|
||||
_rl_sigcleanarg = 0;
|
||||
}
|
||||
_rl_complete_display_matches_interrupt = 0;
|
||||
_rl_abort_internal ();
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* */
|
||||
/* Completion utility functions */
|
||||
@@ -611,7 +625,7 @@ get_y_or_n (int for_pager)
|
||||
if (c == 'n' || c == 'N' || c == RUBOUT)
|
||||
return (0);
|
||||
if (c == ABORT_CHAR || c < 0)
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
if (for_pager && (c == NEWLINE || c == RETURN))
|
||||
return (2);
|
||||
if (for_pager && (c == 'q' || c == 'Q'))
|
||||
@@ -643,6 +657,11 @@ _rl_internal_pager (int lines)
|
||||
n = _rl_screenheight / 2;
|
||||
return (lines > n) ? (lines - n) : -1;
|
||||
}
|
||||
else if (i < 0)
|
||||
{
|
||||
_rl_abort_completion ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -1812,14 +1831,17 @@ display_matches (char **matches)
|
||||
rl_crlf ();
|
||||
fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
|
||||
fflush (rl_outstream);
|
||||
if ((completion_y_or_n = get_y_or_n (0)) == 0)
|
||||
if ((completion_y_or_n = get_y_or_n (0)) <= 0)
|
||||
{
|
||||
rl_crlf ();
|
||||
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
return;
|
||||
if (completion_y_or_n < 0)
|
||||
_rl_abort_completion ();
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ extern void _rl_audit_tty (char *);
|
||||
|
||||
extern int _rl_tropen (void);
|
||||
|
||||
extern int _rl_abort_internal (void);
|
||||
extern void _rl_abort_internal (void) __attribute__((noreturn));
|
||||
extern int _rl_null_function (int, int);
|
||||
extern char *_rl_strindex (const char *, const char *);
|
||||
extern int _rl_strcaseeqn (const char *, const char *, size_t, int);
|
||||
|
||||
+3
-3
@@ -95,7 +95,7 @@ _rl_walphabetic (WCHAR_T wc)
|
||||
#endif
|
||||
|
||||
/* How to abort things. */
|
||||
int
|
||||
void
|
||||
_rl_abort_internal (void)
|
||||
{
|
||||
if (RL_ISSTATE (RL_STATE_TIMEOUT) == 0)
|
||||
@@ -115,13 +115,13 @@ _rl_abort_internal (void)
|
||||
_rl_command_to_execute = 0;
|
||||
|
||||
_rl_longjmp (_rl_top_level, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_abort (int count, int key)
|
||||
{
|
||||
return (_rl_abort_internal ());
|
||||
_rl_abort_internal ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in new issue
Block a user