From 31bc8bef63fdb92c6ea776e093243eb421247f22 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2013 21:51:03 +0200 Subject: [PATCH] Issue #17289: The readline module now plays nicer with external modules or applications changing the rl_completer_word_break_characters global variable. Initial patch by Bradley Froehle. --- Misc/NEWS | 4 ++++ Modules/readline.c | 27 +++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 4c3f83339860..7989eb323be3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -34,6 +34,10 @@ Core and Builtins Library ------- +- Issue #17289: The readline module now plays nicer with external modules + or applications changing the rl_completer_word_break_characters global + variable. Initial patch by Bradley Froehle. + - Issue #12181: select module: Fix struct kevent definition on OpenBSD 64-bit platforms. Patch by Federico Schwindt. diff --git a/Modules/readline.c b/Modules/readline.c index b5e258db67e4..233ebf95ad1b 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -69,6 +69,10 @@ on_completion_display_matches_hook(char **matches, int num_matches, int max_length); +/* Memory allocated for rl_completer_word_break_characters + (see issue #17289 for the motivation). */ +static char *completer_word_break_characters; + /* Exported function to send one line to readline's init file parser */ static PyObject * @@ -344,12 +348,20 @@ set_completer_delims(PyObject *self, PyObject *args) { char *break_chars; - if(!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) { + if (!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) { return NULL; } - free((void*)rl_completer_word_break_characters); - rl_completer_word_break_characters = strdup(break_chars); - Py_RETURN_NONE; + /* Keep a reference to the allocated memory in the module state in case + some other module modifies rl_completer_word_break_characters + (see issue #17289). */ + free(completer_word_break_characters); + completer_word_break_characters = strdup(break_chars); + if (completer_word_break_characters) { + rl_completer_word_break_characters = completer_word_break_characters; + Py_RETURN_NONE; + } + else + return PyErr_NoMemory(); } PyDoc_STRVAR(doc_set_completer_delims, @@ -893,7 +905,8 @@ setup_readline(void) /* Set our completion function */ rl_attempted_completion_function = (CPPFunction *)flex_complete; /* Set Python word break characters */ - rl_completer_word_break_characters = + completer_word_break_characters = + rl_completer_word_break_characters = strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?"); /* All nonalphanums except '.' */ @@ -906,7 +919,7 @@ setup_readline(void) */ #ifdef __APPLE__ if (using_libedit_emulation) - rl_read_init_file(NULL); + rl_read_init_file(NULL); else #endif /* __APPLE__ */ rl_initialize(); @@ -1137,8 +1150,6 @@ initreadline(void) if (m == NULL) return; - - PyOS_ReadlineFunctionPointer = call_readline; setup_readline(); } -- 2.47.3