Issue #9450: Fix memory leaks in readline.remove/replace_history_entry.
This commit is contained in:
parent
38557f2ac9
commit
29b238e0dc
|
@ -21,6 +21,9 @@ Core and Builtins
|
|||
Extensions
|
||||
----------
|
||||
|
||||
- Issue #9450: Fix memory leak in readline.replace_history_item and
|
||||
readline.remove_history_item for readline version >= 5.0.
|
||||
|
||||
- Issue #8105: Validate file descriptor passed to mmap.mmap on Windows.
|
||||
|
||||
- Issue #8046: Add context manager protocol support and .closed property
|
||||
|
|
|
@ -378,6 +378,38 @@ PyDoc_STRVAR(doc_set_completer_delims,
|
|||
"set_completer_delims(string) -> None\n\
|
||||
set the readline word delimiters for tab-completion");
|
||||
|
||||
/* _py_free_history_entry: Utility function to free a history entry. */
|
||||
|
||||
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500
|
||||
|
||||
/* Readline version >= 5.0 introduced a timestamp field into the history entry
|
||||
structure; this needs to be freed to avoid a memory leak. This version of
|
||||
readline also introduced the handy 'free_history_entry' function, which
|
||||
takes care of the timestamp. */
|
||||
|
||||
static void
|
||||
_py_free_history_entry(HIST_ENTRY *entry)
|
||||
{
|
||||
histdata_t data = free_history_entry(entry);
|
||||
free(data);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* No free_history_entry function; free everything manually. */
|
||||
|
||||
static void
|
||||
_py_free_history_entry(HIST_ENTRY *entry)
|
||||
{
|
||||
if (entry->line)
|
||||
free((void *)entry->line);
|
||||
if (entry->data)
|
||||
free(entry->data);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
py_remove_history(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -399,12 +431,7 @@ py_remove_history(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
}
|
||||
/* free memory allocated for the history entry */
|
||||
if (entry->line)
|
||||
free(entry->line);
|
||||
if (entry->data)
|
||||
free(entry->data);
|
||||
free(entry);
|
||||
|
||||
_py_free_history_entry(entry);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -436,12 +463,7 @@ py_replace_history(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
}
|
||||
/* free memory allocated for the old history entry */
|
||||
if (old_entry->line)
|
||||
free(old_entry->line);
|
||||
if (old_entry->data)
|
||||
free(old_entry->data);
|
||||
free(old_entry);
|
||||
|
||||
_py_free_history_entry(old_entry);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue