[pygi] Don't free transfer full struct pointers because we can't do it safely



commit 606018a2c551d890fc2bb987d99683f777598bda
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon Jun 7 16:32:29 2010 -0400

    Don't free transfer full struct pointers because we can't do it safely
    
    * Most libraries which are sending back structs as transfer-full
      are either annotated incorrectly or should be sending boxed types
    * It is much better to throw a warning and leak memory than it is to
      call free on an unknown struct pointer.  Doing so may cause
      a double free
    * Specific case is gdk_atom_intern where a GdkAtom is not actually a pointer
      but an integer stuffed into a pointer type
    
    https://bugzilla.gnome.org/show_bug.cgi?id=620898

 gi/pygi-argument.c |    9 ++++++++-
 gi/pygi-invoke.c   |   11 +++++++++--
 2 files changed, 17 insertions(+), 3 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index ded5b12..76fa58d 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1498,8 +1498,15 @@ _pygi_argument_to_object (GArgument  *arg,
                             break;
                         }
 
+                        if (transfer != GI_TRANSFER_NOTHING)
+                            g_warning ("Transfer mode should be set to None for "
+                                       "struct types as there is no way to free "
+                                       "them safely.  Ignoring transfer mode "
+                                       "to prevent a potential invalid free. "
+                                       "This may cause a leak in your application.");
+
                         object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer,
-                                                    transfer == GI_TRANSFER_EVERYTHING);
+                                                    FALSE);
 
                         Py_DECREF (py_type);
                     } else {
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 16b4037..13ebe80 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -670,8 +670,15 @@ _process_invocation_state (struct invocation_state *state,
                         PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
                         break;
                     }
-                    g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
-                    state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, transfer == GI_TRANSFER_EVERYTHING);
+
+                    if (transfer != GI_TRANSFER_NOTHING)
+                        g_warning ("Transfer mode should be set to None for "
+                                   "struct types as there is no way to free "
+                                   "them safely.  Ignoring transfer mode "
+                                   "to prevent a potential invalid free. "
+                                   "This may cause a leak in your application.");
+
+                    state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, FALSE);
                 } else {
                     PyErr_Format (PyExc_TypeError, "cannot create '%s' instances", py_type->tp_name);
                     g_base_info_unref (info);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]