mirror of https://github.com/python/cpython
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
a14034872b
commit
5d4121a631
|
@ -76,6 +76,10 @@ Core and Builtins
|
|||
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.
|
||||
Original patch by Ronald Oussoren.
|
||||
|
||||
- Issue #18919: If the close() method of a writer in the sunau or wave module
|
||||
failed, second invocation of close() and destructor no more raise an
|
||||
exception.
|
||||
|
|
|
@ -54,14 +54,16 @@ extern char **completion_matches(char *, CPFunction *);
|
|||
* with the "real" readline and cannot be detected at compile-time,
|
||||
* hence we use a runtime check to detect if we're using libedit
|
||||
*
|
||||
* Currently there is one know API incompatibility:
|
||||
* Currently there is one known API incompatibility:
|
||||
* - 'get_history' has a 1-based index with GNU readline, and a 0-based
|
||||
* index with libedit's emulation.
|
||||
* index with older versions of libedit's emulation.
|
||||
* - Note that replace_history and remove_history use a 0-based index
|
||||
* with both implementation.
|
||||
* with both implementations.
|
||||
*/
|
||||
static int using_libedit_emulation = 0;
|
||||
static const char libedit_version_tag[] = "EditLine wrapper";
|
||||
|
||||
static int libedit_history_start = 0;
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
|
||||
|
@ -579,21 +581,21 @@ get_history_item(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
#ifdef __APPLE__
|
||||
if (using_libedit_emulation) {
|
||||
/* Libedit emulation uses 0-based indexes,
|
||||
* the real one uses 1-based indexes,
|
||||
* adjust the index to ensure that Python
|
||||
* code doesn't have to worry about the
|
||||
* difference.
|
||||
/* Older versions of libedit's readline emulation
|
||||
* use 0-based indexes, while readline and newer
|
||||
* versions of libedit use 1-based indexes.
|
||||
*/
|
||||
int length = _py_get_history_length();
|
||||
idx --;
|
||||
|
||||
idx = idx - 1 + libedit_history_start;
|
||||
|
||||
/*
|
||||
* Apple's readline emulation crashes when
|
||||
* the index is out of range, therefore
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
@ -908,6 +910,17 @@ setup_readline(void)
|
|||
*/
|
||||
if (using_libedit_emulation)
|
||||
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__ */
|
||||
|
||||
using_history();
|
||||
|
@ -1116,11 +1129,8 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
|||
if (length > 0)
|
||||
#ifdef __APPLE__
|
||||
if (using_libedit_emulation) {
|
||||
/*
|
||||
* Libedit's emulation uses 0-based indexes,
|
||||
* the real readline uses 1-based indexes.
|
||||
*/
|
||||
line = (const char *)history_get(length - 1)->line;
|
||||
/* handle older 0-based or newer 1-based indexing */
|
||||
line = (const char *)history_get(length + libedit_history_start - 1)->line;
|
||||
} else
|
||||
#endif /* __APPLE__ */
|
||||
line = (const char *)history_get(length)->line;
|
||||
|
|
Loading…
Reference in New Issue