Trent Nelson wrote on Mon, Jan 23, 2012 at 15:07:20 -0500: > 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
Is svn_swig_py_c_strings_to_list() affected too? It appends a string to a list but doesn't Py_DECREF() the string. > 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 <tr...@snakebite.org> > Tested on: FreeBSD, OS X, Windows. > > * 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. > Add 'apr_array_header_t *' and 'swig_type_info *' casts where necessary > to suppress compiler warnings. Those casts shouldn't be needed -- casts from 'void *' to other pointer types are valid C. What warnings were you seeing? > Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c > =================================================================== > --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c > (revision 1234786) > +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c > (working copy) > @@ -653,15 +653,27 @@ > static PyObject *convert_rangelist(void *value, void *ctx, PyObject *py_pool) > { > int i; > + int result; > + PyObject *obj; > PyObject *list; > - apr_array_header_t *array = value; > + apr_array_header_t *array = (apr_array_header_t *)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) > + > + obj = convert_to_swigtype(range, (swig_type_info *)ctx, py_pool); > + if (obj == NULL) > goto error; > + > + result = PyList_Append(list, obj); > + Py_DECREF(obj); > + if (result == -1) > + goto error; > } > return list; > error: