Merged revisions 83670 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83670 | mark.dickinson | 2010-08-03 17:49:49 +0100 (Tue, 03 Aug 2010) | 3 lines

  Issue #8065:  Fix another memory leak in readline module, from failure to free
  the result of a call to history_get_history_state.
........
This commit is contained in:
Mark Dickinson 2010-08-03 16:54:19 +00:00
parent 4ee9853028
commit 0f98128d6e
2 changed files with 29 additions and 19 deletions

View File

@ -133,6 +133,9 @@ Library
Extension Modules
-----------------
- Issue #8065: Fix memory leak in readline module (from failure to
free the result of history_get_history_state()).
- Issue #9450: Fix memory leak in readline.replace_history_item and
readline.remove_history_item for readline version >= 5.0.

View File

@ -512,6 +512,25 @@ PyDoc_STRVAR(doc_get_completer,
\n\
Returns current completer function.");
/* Private function to get current length of history. XXX It may be
* possible to replace this with a direct use of history_length instead,
* but it's not clear whether BSD's libedit keeps history_length up to date.
* See issue #8065.*/
static int
_py_get_history_length(void)
{
HISTORY_STATE *hist_st = history_get_history_state();
int length = hist_st->length;
/* the history docs don't say so, but the address of hist_st changes each
time history_get_history_state is called which makes me think it's
freshly malloc'd memory... on the other hand, the address of the last
line stays the same as long as history isn't extended, so it appears to
be malloc'd but managed by the history package... */
free(hist_st);
return length;
}
/* Exported function to get any element of history */
static PyObject *
@ -530,9 +549,7 @@ get_history_item(PyObject *self, PyObject *args)
* code doesn't have to worry about the
* difference.
*/
HISTORY_STATE *hist_st;
hist_st = history_get_history_state();
int length = _py_get_history_length();
idx --;
/*
@ -540,7 +557,7 @@ get_history_item(PyObject *self, PyObject *args)
* the index is out of range, therefore
* test for that and fail gracefully.
*/
if (idx < 0 || idx >= hist_st->length) {
if (idx < 0 || idx >= length) {
Py_RETURN_NONE;
}
}
@ -562,10 +579,7 @@ return the current contents of history item at index.");
static PyObject *
get_current_history_length(PyObject *self, PyObject *noarg)
{
HISTORY_STATE *hist_st;
hist_st = history_get_history_state();
return PyInt_FromLong(hist_st ? (long) hist_st->length : (long) 0);
return PyInt_FromLong((long)_py_get_history_length());
}
PyDoc_STRVAR(doc_get_current_history_length,
@ -1046,29 +1060,22 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
n = strlen(p);
if (n > 0) {
const char *line;
HISTORY_STATE *state = history_get_history_state();
if (state->length > 0)
int length = _py_get_history_length();
if (length > 0)
#ifdef __APPLE__
if (using_libedit_emulation) {
/*
* Libedit's emulation uses 0-based indexes,
* the real readline uses 1-based indexes.
*/
line = history_get(state->length - 1)->line;
line = history_get(length - 1)->line;
} else
#endif /* __APPLE__ */
line = history_get(state->length)->line;
line = history_get(length)->line;
else
line = "";
if (strcmp(p, line))
add_history(p);
/* the history docs don't say so, but the address of state
changes each time history_get_history_state is called
which makes me think it's freshly malloc'd memory...
on the other hand, the address of the last line stays the
same as long as history isn't extended, so it appears to
be malloc'd but managed by the history package... */
free(state);
}
/* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
release the original. */