Author: danielsh Date: Tue Jan 24 14:28:06 2012 New Revision: 1235264 URL: http://svn.apache.org/viewvc?rev=1235264&view=rev Log: Fix a memory leak in convert_rangelist by *always* Py_DECREF'ing the object returned by convert_to_swigtype (a SWIG wrapper around svn_merge_range_t) once we've established it's not NULL.
This is required because PyList_Append takes ownership of references passed in (i.e. calls Py_INCREF). Prior to this fix, the reference counts of any svn_merge_range_t objects would always be off-by-one, preventing them from ever being garbage collected, having dire effects on the memory usage of long-running programs calling svn_mergeinfo_parse() on real-world data. Patch by: Trent Nelson <[email protected]> Tested on: FreeBSD, OS X, Windows. (this is part of a patch that also included a test suite portion) * subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c: (convert_rangelist): Make sure we call Py_DECREF on the object returned from convert_to_swigtype. PyList_New might return NULL; check for that. Modified: subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Modified: subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1235264&r1=1235263&r2=1235264&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original) +++ subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Tue Jan 24 14:28:06 2012 @@ -657,10 +657,22 @@ static PyObject *convert_rangelist(void apr_array_header_t *array = value; list = PyList_New(0); + if (list == NULL) + return NULL; + for (i = 0; i < array->nelts; i++) { svn_merge_range_t *range = APR_ARRAY_IDX(array, i, svn_merge_range_t *); - if (PyList_Append(list, convert_to_swigtype(range, ctx, py_pool)) == -1) + PyObject *obj; + int result; + + obj = convert_to_swigtype(range, ctx, py_pool); + if (obj == NULL) + goto error; + + result = PyList_Append(list, obj); + Py_DECREF(obj); + if (result == -1) goto error; } return list;
