summaryrefslogtreecommitdiffstats
path: root/Modules/readline.c
diff options
context:
space:
mode:
authorNed Deily <nad@acm.org>2013-09-06 22:16:19 (GMT)
committerNed Deily <nad@acm.org>2013-09-06 22:16:19 (GMT)
commitf70f4a63b67805c77834e198644b1b5a958fb4f5 (patch)
tree313b26c247ee39d70ea049263c27d46d58d3ec4c /Modules/readline.c
parentf4ecfae75f9e4e52c07e5561077855aebaa6e77a (diff)
downloadcpython-f70f4a63b67805c77834e198644b1b5a958fb4f5.zip
cpython-f70f4a63b67805c77834e198644b1b5a958fb4f5.tar.gz
cpython-f70f4a63b67805c77834e198644b1b5a958fb4f5.tar.bz2
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.
Diffstat (limited to 'Modules/readline.c')
-rw-r--r--Modules/readline.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/Modules/readline.c b/Modules/readline.c
index ab24636..c154e1d 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -63,6 +63,8 @@ extern char **completion_matches(char *, CPFunction *);
*/
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
@@ -627,21 +629,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;
}
}
@@ -974,6 +976,17 @@ setup_readline(readlinestate *mod_state)
*/
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();
@@ -1178,11 +1191,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;