]> granicus.if.org Git - python/commitdiff
Merged revisions 83667 via svnmerge from
authorMark Dickinson <dickinsm@gmail.com>
Tue, 3 Aug 2010 16:14:09 +0000 (16:14 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Tue, 3 Aug 2010 16:14:09 +0000 (16:14 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83667 | mark.dickinson | 2010-08-03 17:08:16 +0100 (Tue, 03 Aug 2010) | 2 lines

  Issue #9450:  Fix memory leaks in readline.remove/replace_history_entry.
........

Misc/NEWS
Modules/readline.c

index 624c4655789b8d9f761001043002b85cc2e73f96..6ed2c2c1ea0b7d769e9f4212fed47d5918d5e1a0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -383,6 +383,9 @@ Library
 Extension Modules
 -----------------
 
+- 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 #9422: Fix memory leak when re-initializing a struct.Struct object.
index e4a1d55e058a8dfbe0c11891a5485d915fa6f366..e187129dfa34b25244964dc343742c909ad8144c 100644 (file)
@@ -334,6 +334,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)
 {
@@ -355,12 +387,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;
 }
 
@@ -392,12 +419,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;
 }