mirror of
https://github.com/python/cpython.git
synced 2025-12-10 11:00:14 +00:00
Issue #18458: Prevent crashes with newer versions of libedit. Its readline
emulation has changed from 0-based indexing to 1-based like gnu readline. Original patch by Ronald Oussoren.
This commit is contained in:
parent
f4ecfae75f
commit
f70f4a63b6
2 changed files with 25 additions and 12 deletions
|
|
@ -56,6 +56,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #18458: Prevent crashes with newer versions of libedit. Its readline
|
||||||
|
emulation has changed from 0-based indexing to 1-based like gnu readline.
|
||||||
|
|
||||||
- Issue #18852: Handle case of ``readline.__doc__`` being ``None`` in the new
|
- Issue #18852: Handle case of ``readline.__doc__`` being ``None`` in the new
|
||||||
readline activation code in ``site.py``.
|
readline activation code in ``site.py``.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ extern char **completion_matches(char *, CPFunction *);
|
||||||
*/
|
*/
|
||||||
static int using_libedit_emulation = 0;
|
static int using_libedit_emulation = 0;
|
||||||
static const char libedit_version_tag[] = "EditLine wrapper";
|
static const char libedit_version_tag[] = "EditLine wrapper";
|
||||||
|
|
||||||
|
static int libedit_history_start = 0;
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
|
#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
|
||||||
|
|
@ -627,21 +629,21 @@ get_history_item(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (using_libedit_emulation) {
|
if (using_libedit_emulation) {
|
||||||
/* Libedit emulation uses 0-based indexes,
|
/* Older versions of libedit's readline emulation
|
||||||
* the real one uses 1-based indexes,
|
* use 0-based indexes, while readline and newer
|
||||||
* adjust the index to ensure that Python
|
* versions of libedit use 1-based indexes.
|
||||||
* code doesn't have to worry about the
|
|
||||||
* difference.
|
|
||||||
*/
|
*/
|
||||||
int length = _py_get_history_length();
|
int length = _py_get_history_length();
|
||||||
idx --;
|
|
||||||
|
idx = idx - 1 + libedit_history_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apple's readline emulation crashes when
|
* Apple's readline emulation crashes when
|
||||||
* the index is out of range, therefore
|
* the index is out of range, therefore
|
||||||
* test for that and fail gracefully.
|
* test for that and fail gracefully.
|
||||||
*/
|
*/
|
||||||
if (idx < 0 || idx >= length) {
|
if (idx < (0 + libedit_history_start)
|
||||||
|
|| idx >= (length + libedit_history_start)) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -974,6 +976,17 @@ setup_readline(readlinestate *mod_state)
|
||||||
*/
|
*/
|
||||||
if (using_libedit_emulation)
|
if (using_libedit_emulation)
|
||||||
rl_initialize();
|
rl_initialize();
|
||||||
|
|
||||||
|
/* Detect if libedit's readline emulation uses 0-based
|
||||||
|
* indexing or 1-based indexing.
|
||||||
|
*/
|
||||||
|
add_history("1");
|
||||||
|
if (history_get(1) == NULL) {
|
||||||
|
libedit_history_start = 0;
|
||||||
|
} else {
|
||||||
|
libedit_history_start = 1;
|
||||||
|
}
|
||||||
|
clear_history();
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
using_history();
|
using_history();
|
||||||
|
|
@ -1178,11 +1191,8 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (using_libedit_emulation) {
|
if (using_libedit_emulation) {
|
||||||
/*
|
/* handle older 0-based or newer 1-based indexing */
|
||||||
* Libedit's emulation uses 0-based indexes,
|
line = (const char *)history_get(length + libedit_history_start - 1)->line;
|
||||||
* the real readline uses 1-based indexes.
|
|
||||||
*/
|
|
||||||
line = (const char *)history_get(length - 1)->line;
|
|
||||||
} else
|
} else
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
line = (const char *)history_get(length)->line;
|
line = (const char *)history_get(length)->line;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue