r31079 - in /desktop/experimental/pygobject/debian: changelog patches/00git_marshal_gvariant_arrays.patch patches/series

mpitt at users.alioth.debian.org mpitt at users.alioth.debian.org
Thu Oct 27 05:10:53 UTC 2011


Author: mpitt
Date: Thu Oct 27 05:10:53 2011
New Revision: 31079

URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=31079
Log:
Add 00git_marshal_gvariant_arrays.patch: Fix marshaling of arrays of
GVariants. Thanks Mikkel Kamstrup Erlandsen! (LP: #855402)

Added:
    desktop/experimental/pygobject/debian/patches/00git_marshal_gvariant_arrays.patch
Modified:
    desktop/experimental/pygobject/debian/changelog
    desktop/experimental/pygobject/debian/patches/series

Modified: desktop/experimental/pygobject/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/experimental/pygobject/debian/changelog?rev=31079&op=diff
==============================================================================
--- desktop/experimental/pygobject/debian/changelog [utf-8] (original)
+++ desktop/experimental/pygobject/debian/changelog [utf-8] Thu Oct 27 05:10:53 2011
@@ -6,6 +6,8 @@
     needs methods from that version.
   * debian/rules: Have test failures fail the build. This should finally work
     now, and will prevent unnoticed architecture specific regressions.
+  * Add 00git_marshal_gvariant_arrays.patch: Fix marshaling of arrays of
+    GVariants. Thanks Mikkel Kamstrup Erlandsen! (LP: #855402)
 
  -- Martin Pitt <mpitt at debian.org>  Thu, 27 Oct 2011 07:01:57 +0200
 

Added: desktop/experimental/pygobject/debian/patches/00git_marshal_gvariant_arrays.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/experimental/pygobject/debian/patches/00git_marshal_gvariant_arrays.patch?rev=31079&op=file
==============================================================================
--- desktop/experimental/pygobject/debian/patches/00git_marshal_gvariant_arrays.patch (added)
+++ desktop/experimental/pygobject/debian/patches/00git_marshal_gvariant_arrays.patch [utf-8] Thu Oct 27 05:10:53 2011
@@ -1,0 +1,254 @@
+From c7aa0e79dfb4c1092c51ae1464b8414083b4f3fc Mon Sep 17 00:00:00 2001
+From: Mikkel Kamstrup Erlandsen <mikkel.kamstrup at canonical.com>
+Date: Tue, 4 Oct 2011 12:28:26 +0200
+Subject: [PATCH] fix marshaling of arrays of GVariants
+
+Add unit tests for marshaling of arrays of variants with all
+transfer modes. Requires latest gobject-introspection.
+
+Plug potential leaks of GArray data members
+
+Fix calling of wrong cleanup_from_py for arrays
+
+Simplify and fix logic for cleaning up arrays both in from_py()
+and to_py() code paths.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=638915
+
+Signed-off-by: Martin Pitt <martin.pitt at ubuntu.com>
+---
+ gi/pygi-cache.c           |    2 +-
+ gi/pygi-marshal-cleanup.c |   81 +++++++++++++++++++++++++++++----------------
+ gi/pygi-marshal-from-py.c |   10 ++++-
+ gi/pygi-marshal-to-py.c   |   13 ++++++-
+ tests/test_gi.py          |   14 +++++++-
+ 5 files changed, 85 insertions(+), 35 deletions(-)
+
+diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
+index 41ca32c..5dc811a 100644
+--- a/gi/pygi-cache.c
++++ b/gi/pygi-cache.c
+@@ -498,7 +498,7 @@ _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
+         callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
+     }
+ 
+-    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_to_py_array;
++    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
+ 
+     return TRUE;
+ }
+diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
+index 8ed9bdb..f80ebfa 100644
+--- a/gi/pygi-marshal-cleanup.c
++++ b/gi/pygi-marshal-cleanup.c
+@@ -273,6 +273,37 @@ _pygi_marshal_cleanup_to_py_interface_struct_foreign (PyGIInvokeState *state,
+             data);
+ }
+ 
++static GArray*
++_wrap_c_array (PyGIInvokeState   *state,
++               PyGISequenceCache *sequence_cache,
++               gpointer           data)
++{
++    GArray *array_;
++    gsize   len;
++  
++    if (sequence_cache->fixed_size >= 0) {
++        len = sequence_cache->fixed_size;
++    } else if (sequence_cache->is_zero_terminated) {
++        len = g_strv_length ((gchar **)data);
++    } else {
++        GIArgument *len_arg = state->args[sequence_cache->len_arg_index];
++        len = len_arg->v_long;
++    }
++
++    array_ = g_array_new (FALSE,
++                          FALSE,
++                          sequence_cache->item_size);
++
++    if (array_ == NULL)
++        return NULL;
++
++    g_free (array_->data);
++    array_->data = data;
++    array_->len = len;
++
++    return array_;
++}
++
+ void
+ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
+                                      PyGIArgCache    *arg_cache,
+@@ -286,26 +317,11 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
+         /* If this isn't a garray create one to help process variable sized
+            array elements */
+         if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
+-            gsize len;
+-            if (sequence_cache->fixed_size >= 0) {
+-                len = sequence_cache->fixed_size;
+-            } else if (sequence_cache->is_zero_terminated) {
+-                len = g_strv_length ((gchar **)data);
+-            } else {
+-                GIArgument *len_arg = state->args[sequence_cache->len_arg_index];
+-                len = len_arg->v_long;
+-            }
+-
+-            array_ = g_array_new (FALSE,
+-                                  FALSE,
+-                                  sequence_cache->item_size);
+-
++            array_ = _wrap_c_array (state, sequence_cache, data);
++            
+             if (array_ == NULL)
+                 return;
+-
+-            array_->data = data;
+-            array_->len = len;
+-
++            
+         } else {
+             array_ = (GArray *) data;
+         }
+@@ -324,12 +340,12 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
+             }
+         }
+ 
+-        if (state->failed ||
+-            arg_cache->transfer == GI_TRANSFER_NOTHING ||
+-            arg_cache->transfer == GI_TRANSFER_CONTAINER) {
++        /* Only free the array when we didn't transfer ownership */
++        if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
++            g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING);
++        } else if (state->failed ||
++                   arg_cache->transfer == GI_TRANSFER_NOTHING) {
+             g_array_free (array_, TRUE);
+-        } else if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
+-            g_array_free (array_, FALSE);
+         }
+     }
+ }
+@@ -343,12 +359,20 @@ _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
+     PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
+ 
+     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING ||
+-            arg_cache->transfer == GI_TRANSFER_CONTAINER) {
+-        GArray *array_ = (GArray *) data;
++        arg_cache->transfer == GI_TRANSFER_CONTAINER) {
++        GArray *array_;
++        PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
+ 
++        /* If this isn't a garray create one to help process variable sized
++           array elements */
+         if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
+-            g_free (data);
+-            return;
++            array_ = _wrap_c_array (state, sequence_cache, data);
++            
++            if (array_ == NULL)
++                return;
++            
++        } else {
++            array_ = (GArray *) data;
+         }
+ 
+         if (sequence_cache->item_cache->to_py_cleanup != NULL) {
+@@ -363,8 +387,7 @@ _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
+             }
+         }
+ 
+-        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+-            g_array_free (array_, TRUE);
++        g_array_free (array_, TRUE);
+     }
+ }
+ 
+diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
+index 1f807b4..0a94ffe 100644
+--- a/gi/pygi-marshal-from-py.c
++++ b/gi/pygi-marshal-from-py.c
+@@ -831,8 +831,14 @@ _pygi_marshal_from_py_array (PyGIInvokeState   *state,
+                     PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
+                     gboolean is_boxed = g_type_is_a (item_iface_cache->g_type, G_TYPE_BOXED);
+                     gboolean is_gvalue = item_iface_cache->g_type == G_TYPE_VALUE;
+-
+-                    if (!is_boxed || is_gvalue) {
++                    gboolean is_gvariant = item_iface_cache->g_type == G_TYPE_VARIANT;
++                    
++                    if (is_gvariant) {
++                        /* Item size will always be that of a pointer,
++                         * since GVariants are opaque hence always passed by ref */
++                        g_assert (item_size == sizeof (item.v_pointer));
++                        g_array_insert_val (array_, i, item.v_pointer);
++                    } else if (!is_boxed || is_gvalue) {
+                         memcpy (array_->data + (i * item_size), item.v_pointer, item_size);
+                         if (from_py_cleanup)
+                             from_py_cleanup (state, item_arg_cache, item.v_pointer, TRUE);
+diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
+index 48dfa08..984e7c1 100644
+--- a/gi/pygi-marshal-to-py.c
++++ b/gi/pygi-marshal-to-py.c
+@@ -292,7 +292,8 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
+ 
+             return NULL;
+         }
+-
++        
++        g_free (array_->data);
+         array_->data = arg->v_pointer;
+         array_->len = len;
+     }
+@@ -331,10 +332,18 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
+                     item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
+                 } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
+                     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
++                    gboolean is_gvariant = iface_cache->g_type == G_TYPE_VARIANT;
+ 
++                    // FIXME: This probably doesn't work with boxed types or gvalues. See fx. _pygi_marshal_from_py_array()
+                     switch (g_base_info_get_type (iface_cache->interface_info)) {
+                         case GI_INFO_TYPE_STRUCT:
+-                            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
++                            if (is_gvariant) {
++                              g_assert (item_size == sizeof (gpointer));
++                              if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
++                                item_arg.v_pointer = g_variant_ref_sink (g_array_index (array_, gpointer, i));
++                              else
++                                item_arg.v_pointer = g_array_index (array_, gpointer, i);
++                            } else if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+                                 gpointer *_struct = g_malloc (item_size);
+                                 memcpy (_struct, array_->data + i * item_size,
+                                         item_size);
+diff --git a/tests/test_gi.py b/tests/test_gi.py
+index dd91cb8..11ee2a4 100644
+--- a/tests/test_gi.py
++++ b/tests/test_gi.py
+@@ -10,7 +10,7 @@ import shutil
+ import os
+ import locale
+ import subprocess
+-from gi.repository import GObject
++from gi.repository import GObject, GLib
+ 
+ from gi.repository import GIMarshallingTests
+ 
+@@ -769,6 +769,18 @@ class TestArray(unittest.TestCase):
+ 
+     def test_gstrv_inout(self):
+         self.assertEquals(['-1', '0', '1', '2'], GIMarshallingTests.gstrv_inout(['0', '1', '2']))
++    
++    def test_array_gvariant_none_in(self):
++        v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
++        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
++    
++    def test_array_gvariant_container_in(self):
++        v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
++        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
++    
++    def test_array_gvariant_full_in(self):
++        v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
++        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
+ 
+ class TestGArray(unittest.TestCase):
+ 
+-- 
+1.7.5.4
+

Modified: desktop/experimental/pygobject/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/experimental/pygobject/debian/patches/series?rev=31079&op=diff
==============================================================================
--- desktop/experimental/pygobject/debian/patches/series [utf-8] (original)
+++ desktop/experimental/pygobject/debian/patches/series [utf-8] Thu Oct 27 05:10:53 2011
@@ -1,0 +1,1 @@
+00git_marshal_gvariant_arrays.patch




More information about the pkg-gnome-commits mailing list