Commit 105e6738 authored by Martin Pitt's avatar Martin Pitt
Browse files

Fix leak of caller-allocated boxed values

Add a new "allocated_slice" argument to _pygi_boxed_new() which specifies
whether its "boxed" pointer was allocated using a slice (by giving its size) or
malloc (by specifying 0), as _pygi_boxed_new cannot determine that itself any
more.

Use this in _pygi_marshal_to_py_interface_struct() for caller-allocated boxed
values, as _caller_alloc() uses _pygi_boxed_alloc() for those (i. e. slices),
which would otherwise leak.

Thanks to Mike Gorse <mgorse@suse.com> for the original patch!

https://bugzilla.gnome.org/show_bug.cgi?id=691501
parent 64bcca2d
......@@ -513,7 +513,7 @@ _wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
py_type = _pygi_type_import_by_name ("GLib", "VariantType");
py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE, 0);
return py_variant;
}
......
......@@ -1752,7 +1752,7 @@ _pygi_argument_to_object (GIArgument *arg,
if (py_type == NULL)
break;
object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer == GI_TRANSFER_EVERYTHING);
object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer == GI_TRANSFER_EVERYTHING, 0);
Py_DECREF (py_type);
} else if (g_type_is_a (type, G_TYPE_POINTER)) {
......
......@@ -104,7 +104,7 @@ _boxed_new (PyTypeObject *type,
goto out;
}
self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE);
self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE, size);
if (self == NULL) {
g_slice_free1 (size, boxed);
goto out;
......@@ -133,7 +133,8 @@ PYGLIB_DEFINE_TYPE("gi.Boxed", PyGIBoxed_Type, PyGIBoxed);
PyObject *
_pygi_boxed_new (PyTypeObject *type,
gpointer boxed,
gboolean free_on_dealloc)
gboolean free_on_dealloc,
gsize allocated_slice)
{
PyGIBoxed *self;
......@@ -154,8 +155,13 @@ _pygi_boxed_new (PyTypeObject *type,
( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type);
( (PyGBoxed *) self)->boxed = boxed;
( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc;
self->size = 0;
self->slice_allocated = FALSE;
if (allocated_slice > 0) {
self->size = allocated_slice;
self->slice_allocated = TRUE;
} else {
self->size = 0;
self->slice_allocated = FALSE;
}
return (PyObject *) self;
}
......
......@@ -30,7 +30,8 @@ extern PyTypeObject PyGIBoxed_Type;
PyObject * _pygi_boxed_new (PyTypeObject *type,
gpointer boxed,
gboolean free_on_dealloc);
gboolean free_on_dealloc,
gsize allocated_slice);
void * _pygi_boxed_alloc (GIBaseInfo *info,
gsize *size);
......
......@@ -814,8 +814,10 @@ _pygi_marshal_to_py_interface_struct (PyGIInvokeState *state,
py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info,
arg->v_pointer);
} else if (g_type_is_a (type, G_TYPE_BOXED)) {
py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
arg_cache->transfer == GI_TRANSFER_EVERYTHING);
py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->is_caller_allocates,
arg_cache->is_caller_allocates ?
g_struct_info_get_size(iface_cache->interface_info) : 0);
} else if (g_type_is_a (type, G_TYPE_POINTER)) {
if (iface_cache->py_type == NULL ||
!PyType_IsSubtype ( (PyTypeObject *)iface_cache->py_type, &PyGIStruct_Type)) {
......
......@@ -240,7 +240,8 @@ pyg_source_new (void)
source = (PyGRealSource*) g_source_new (&pyg_source_funcs, sizeof (PyGRealSource));
py_type = _pygi_type_import_by_name ("GLib", "Source");
source->obj = _pygi_boxed_new ( (PyTypeObject *) py_type, source, FALSE);
/* g_source_new uses malloc, not slices */
source->obj = _pygi_boxed_new ( (PyTypeObject *) py_type, source, FALSE, 0);
return source->obj;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment