summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2014-03-12 18:32:47 -0400
committerOwen W. Taylor <otaylor@fishsoup.net>2014-03-12 19:01:38 -0400
commitbbfcebdfdc5e574999221b60520422ea6da82435 (patch)
tree4b6bcd0c554183908935222e1c565611a38f8774
parentc5b641cb4eea9ae64a173dcaa4ee5a4accb036f6 (diff)
downloadpygobject-bbfcebdfdc5e574999221b60520422ea6da82435.tar.gz
Handle GI_TRANSFER_EVERYTHING for returns of foreign structures
Any (transfer full) return of a cairo type other than a path was leaked. Pass the transfer type PyGIArgOverrideFromGIArgumentFunc and handle it for the cairo foreign type. For paths we can only handle (transfer full) so throw an error for (transfer none). https://bugzilla.gnome.org/show_bug.cgi?id=726206
-rw-r--r--gi/pygi-foreign-cairo.c32
-rw-r--r--gi/pygi-foreign.c3
-rw-r--r--gi/pygi-foreign.h1
-rw-r--r--gi/pygi-invoke.c1
-rw-r--r--gi/pygi-struct-marshal.c1
-rw-r--r--gi/pygi.h1
6 files changed, 31 insertions, 8 deletions
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 3fe6a39c..8261a07f 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -56,11 +56,14 @@ cairo_context_to_arg (PyObject *value,
}
static PyObject *
-cairo_context_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_context_from_arg (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ gpointer data)
{
cairo_t *context = (cairo_t*) data;
- cairo_reference (context);
+ if (transfer == GI_TRANSFER_NOTHING)
+ cairo_reference (context);
return PycairoContext_FromContext (context, &PycairoContext_Type, NULL);
}
@@ -95,11 +98,14 @@ cairo_surface_to_arg (PyObject *value,
}
static PyObject *
-cairo_surface_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_surface_from_arg (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ gpointer data)
{
cairo_surface_t *surface = (cairo_surface_t*) data;
- cairo_surface_reference (surface);
+ if (transfer == GI_TRANSFER_NOTHING)
+ cairo_surface_reference (surface);
return PycairoSurface_FromSurface (surface, NULL);
}
@@ -134,10 +140,17 @@ cairo_path_to_arg (PyObject *value,
}
static PyObject *
-cairo_path_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_path_from_arg (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ gpointer data)
{
cairo_path_t *path = (cairo_path_t*) data;
+ if (transfer == GI_TRANSFER_NOTHING) {
+ PyErr_SetString(PyExc_TypeError, "Unsupported annotation (transfer none) for cairo.Path return");
+ return NULL;
+ }
+
return PycairoPath_FromPath (path);
}
@@ -170,11 +183,16 @@ cairo_font_options_to_arg (PyObject *value,
}
static PyObject *
-cairo_font_options_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_font_options_from_arg (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ gpointer data)
{
cairo_font_options_t *font_options = (cairo_font_options_t*) data;
- return PycairoFontOptions_FromFontOptions (cairo_font_options_copy (font_options));
+ if (transfer == GI_TRANSFER_NOTHING)
+ font_options = cairo_font_options_copy (font_options);
+
+ return PycairoFontOptions_FromFontOptions (font_options);
}
static PyObject *
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index c046d0fa..f3c1a344 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -123,6 +123,7 @@ pygi_struct_foreign_convert_to_g_argument (PyObject *value,
PyObject *
pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
GIArgument *arg)
{
GIBaseInfo *base_info = (GIBaseInfo *) interface_info;
@@ -131,7 +132,7 @@ pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
if (foreign_struct == NULL)
return NULL;
- return foreign_struct->from_func (interface_info, arg);
+ return foreign_struct->from_func (interface_info, transfer, arg);
}
PyObject *
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index dd5f8967..478d7594 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -35,6 +35,7 @@ PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value,
GITransfer transfer,
GIArgument *arg);
PyObject *pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
GIArgument *arg);
PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,
gpointer struct_);
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 3bb4dc6c..f4abb266 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -401,6 +401,7 @@ _caller_alloc (PyGIArgCache *arg_cache, GIArgument *arg)
PyObject *foreign_struct =
pygi_struct_foreign_convert_from_g_argument (
iface_cache->interface_info,
+ GI_TRANSFER_NOTHING,
NULL);
pygi_struct_foreign_convert_to_g_argument (foreign_struct,
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 338f2be5..7346eae0 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -352,6 +352,7 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg,
py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
} else if (is_foreign) {
py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
+ transfer,
arg->v_pointer);
} else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
if (py_type) {
diff --git a/gi/pygi.h b/gi/pygi.h
index 3a1591f8..ecd3359c 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -85,6 +85,7 @@ typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject *value,
GITransfer transfer,
GIArgument *arg);
typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info,
+ GITransfer transfer,
gpointer data);
typedef PyObject * (*PyGIArgOverrideReleaseFunc) (GITypeInfo *type_info,
gpointer struct_);