[pygobject3] 3.3.4-6: fix issues on big-endian 64-bit machines (rhbz#841596, rhbz#842880)

dmalcolm dmalcolm at fedoraproject.org
Thu Aug 9 19:11:50 UTC 2012


commit aec497d966b2ddbfa0eda56c7057d459df01fb19
Author: David Malcolm <dmalcolm at redhat.com>
Date:   Thu Aug 9 15:10:50 2012 -0400

    3.3.4-6: fix issues on big-endian 64-bit machines (rhbz#841596, rhbz#842880)

 endianness-fixes.patch                            |  545 +++++++++++++++++++++
 fix-list-marshalling-on-big-endian-machines.patch |  185 +++++++
 pygobject3.spec                                   |   20 +-
 test-list-marshalling.patch                       |   15 +
 4 files changed, 764 insertions(+), 1 deletions(-)
---
diff --git a/endianness-fixes.patch b/endianness-fixes.patch
new file mode 100644
index 0000000..ec37071
--- /dev/null
+++ b/endianness-fixes.patch
@@ -0,0 +1,545 @@
+Index: pygobject-3.2.2/gi/pygi-cache.c
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-cache.c
++++ pygobject-3.2.2/gi/pygi-cache.c
+@@ -1379,6 +1379,8 @@ _args_cache_generate (GICallableInfo *ca
+                 callable_cache->n_to_py_child_args++;
+             }
+ 
++            arg_cache->type_tag = g_type_info_get_tag (type_info);
++
+             g_base_info_unref ( (GIBaseInfo *)arg_info);
+             continue;
+         }
+Index: pygobject-3.2.2/gi/pygi-marshal-from-py.c
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-marshal-from-py.c
++++ pygobject-3.2.2/gi/pygi-marshal-from-py.c
+@@ -32,6 +32,119 @@
+ #include "pygi-marshal-cleanup.h"
+ #include "pygi-marshal-from-py.h"
+ 
++gboolean
++gi_argument_from_py_ssize_t (GIArgument   *arg_out,
++                             Py_ssize_t    size_in,
++                             GITypeTag     type_tag)                             
++{
++    switch (type_tag) {
++    case GI_TYPE_TAG_VOID:
++    case GI_TYPE_TAG_BOOLEAN:
++    case GI_TYPE_TAG_INT8:
++    case GI_TYPE_TAG_UINT8:
++    case GI_TYPE_TAG_INT16:
++    case GI_TYPE_TAG_UINT16:
++        goto unhandled_type;
++
++	/* Ranges assume two's complement */
++    case GI_TYPE_TAG_INT32:
++	if (size_in >= G_MININT32 && size_in <= G_MAXINT32) {
++	    arg_out->v_int32 = size_in;
++	    return TRUE;
++	} else {
++            goto overflow;
++	}
++
++    case GI_TYPE_TAG_UINT32:
++	if (size_in >= 0 && size_in <= G_MAXUINT32) {
++	    arg_out->v_uint32 = size_in;
++	    return TRUE;
++	} else {
++            goto overflow;
++	}
++
++    case GI_TYPE_TAG_INT64:
++	arg_out->v_int64 = size_in;
++	return TRUE;
++
++    case GI_TYPE_TAG_UINT64:
++	if (size_in >= 0) {
++	    arg_out->v_uint64 = size_in;
++	    return TRUE;
++	} else {
++            goto overflow;
++	}
++	    
++    case GI_TYPE_TAG_FLOAT:
++    case GI_TYPE_TAG_DOUBLE:
++    case GI_TYPE_TAG_GTYPE:
++    case GI_TYPE_TAG_UTF8:
++    case GI_TYPE_TAG_FILENAME:
++    case GI_TYPE_TAG_ARRAY:
++    case GI_TYPE_TAG_INTERFACE:
++    case GI_TYPE_TAG_GLIST:
++    case GI_TYPE_TAG_GSLIST:
++    case GI_TYPE_TAG_GHASH:
++    case GI_TYPE_TAG_ERROR:
++    case GI_TYPE_TAG_UNICHAR:
++    default:
++        goto unhandled_type;
++    }
++
++ overflow:
++    PyErr_Format (PyExc_OverflowError,
++                  "Unable to marshal C Py_ssize_t %zd to %s",
++                  size_in,
++                  g_type_tag_to_string(type_tag));
++    return FALSE;
++
++ unhandled_type:
++    PyErr_Format (PyExc_TypeError,
++                  "Unable to marshal C Py_ssize_t %zd to %s",
++                  size_in,
++                  g_type_tag_to_string(type_tag));
++    return FALSE;
++}
++
++gboolean
++gi_argument_from_c_long (GIArgument *arg_out,
++			 long        c_long_in,
++			 GITypeTag   type_tag)
++{
++    switch (type_tag) {
++      case GI_TYPE_TAG_INT8:
++	  arg_out->v_int8 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_UINT8:
++	  arg_out->v_uint8 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_INT16:
++	  arg_out->v_int16 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_UINT16:
++	  arg_out->v_uint16 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_INT32:
++	  arg_out->v_int32 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_UINT32:
++	  arg_out->v_uint32 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_INT64:
++	  arg_out->v_int64 = c_long_in;
++	  return TRUE;
++      case GI_TYPE_TAG_UINT64:
++	  arg_out->v_uint64 = c_long_in;
++	  return TRUE;
++      default:
++          PyErr_Format (PyExc_TypeError,
++                        "Unable to marshal C long %ld to %s",
++                        c_long_in,
++                        g_type_tag_to_string(type_tag));
++	  return FALSE;
++    }
++}
++
+ /*
+  * _is_union_member - check to see if the py_arg is actually a member of the
+  * expected C union
+@@ -929,12 +1042,21 @@ array_success:
+         if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) {
+             gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer;
+             /* if we are not setup yet just set the in arg */
+-            if (len_arg == NULL)
+-                state->in_args[child_cache->c_arg_index].v_long = length;
+-            else
++            if (len_arg == NULL) {
++		if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
++                                                  length,
++                                                  child_cache->type_tag)) {
++		    goto err;
++		}
++            } else {
+                 *len_arg = length;
++	    }
+         } else {
+-            state->in_args[child_cache->c_arg_index].v_long = length;
++	    if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
++                                              length,
++                                              child_cache->type_tag)) {
++		goto err;
++	    }
+         }
+     }
+ 
+@@ -1278,20 +1400,32 @@ _pygi_marshal_from_py_interface_enum (Py
+                                       PyObject          *py_arg,
+                                       GIArgument        *arg)
+ {
+-    PyObject *int_;
++    PyObject *py_long;
++    long c_long;
+     gint is_instance;
+     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
++    GIBaseInfo *interface;
+ 
+     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+ 
+-    int_ = PYGLIB_PyNumber_Long (py_arg);
+-    if (int_ == NULL) {
++    py_long = PYGLIB_PyNumber_Long (py_arg);
++    if (py_long == NULL) {
+         PyErr_Clear();
+         goto err;
+     }
+ 
+-    arg->v_long = PYGLIB_PyLong_AsLong (int_);
+-    Py_DECREF (int_);
++    c_long = PYGLIB_PyLong_AsLong (py_long);
++    Py_DECREF (py_long);
++
++    /* Write c_long into arg */
++    interface = g_type_info_get_interface (arg_cache->type_info);
++    assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
++    if (!gi_argument_from_c_long(arg,
++                                 c_long,
++                                 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
++          g_assert_not_reached();
++          return FALSE;
++    }
+ 
+     /* If this is not an instance of the Enum type that we want
+      * we need to check if the value is equivilant to one of the
+@@ -1305,7 +1439,7 @@ _pygi_marshal_from_py_interface_enum (Py
+                 g_enum_info_get_value (iface_cache->interface_info, i);
+             glong enum_value = g_value_info_get_value (value_info);
+             g_base_info_unref ( (GIBaseInfo *)value_info);
+-            if (arg->v_long == enum_value) {
++            if (c_long == enum_value) {
+                 is_found = TRUE;
+                 break;
+             }
+@@ -1330,25 +1464,35 @@ _pygi_marshal_from_py_interface_flags (P
+                                        PyObject          *py_arg,
+                                        GIArgument        *arg)
+ {
+-    PyObject *int_;
++    PyObject *py_long;
++    long c_long;
+     gint is_instance;
+     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
++    GIBaseInfo *interface;
+ 
+     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+ 
+-    int_ = PYGLIB_PyNumber_Long (py_arg);
+-    if (int_ == NULL) {
++    py_long = PYGLIB_PyNumber_Long (py_arg);
++    if (py_long == NULL) {
+         PyErr_Clear ();
+         goto err;
+     }
+ 
+-    arg->v_long = PYGLIB_PyLong_AsLong (int_);
+-    Py_DECREF (int_);
++    c_long = PYGLIB_PyLong_AsLong (py_long);
++    Py_DECREF (py_long);
+ 
+     /* only 0 or argument of type Flag is allowed */
+-    if (!is_instance && arg->v_long != 0)
++    if (!is_instance && c_long != 0)
+         goto err;
+ 
++    /* Write c_long into arg */
++    interface = g_type_info_get_interface (arg_cache->type_info);
++    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
++    if (!gi_argument_from_c_long(arg, c_long,
++                                 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
++        return FALSE;
++    }
++
+     return TRUE;
+ 
+ err:
+Index: pygobject-3.2.2/gi/pygi-marshal-from-py.h
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-marshal-from-py.h
++++ pygobject-3.2.2/gi/pygi-marshal-from-py.h
+@@ -30,6 +30,9 @@
+ 
+ G_BEGIN_DECLS
+ 
++gboolean _pygi_marshal_from_py_ssize_t     (PyGIArgCache      *arg_cache,
++                                            Py_ssize_t         size,
++                                            GIArgument        *arg);
+ gboolean _pygi_marshal_from_py_void        (PyGIInvokeState   *state,
+                                             PyGICallableCache *callable_cache,
+                                             PyGIArgCache      *arg_cache,
+Index: pygobject-3.2.2/gi/pygi-marshal-to-py.c
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-marshal-to-py.c
++++ pygobject-3.2.2/gi/pygi-marshal-to-py.c
+@@ -34,6 +34,83 @@
+ #include "pygi-marshal-cleanup.h"
+ #include "pygi-marshal-to-py.h"
+ 
++gboolean
++gi_argument_to_c_long (GIArgument *arg_in,
++                       long *c_long_out,
++                       GITypeTag type_tag)
++{
++    switch (type_tag) {
++      case GI_TYPE_TAG_INT8:
++          *c_long_out = arg_in->v_int8;
++          return TRUE;
++      case GI_TYPE_TAG_UINT8:
++          *c_long_out = arg_in->v_uint8;
++          return TRUE;
++      case GI_TYPE_TAG_INT16:
++          *c_long_out = arg_in->v_int16;
++          return TRUE;
++      case GI_TYPE_TAG_UINT16:
++          *c_long_out = arg_in->v_uint16;
++          return TRUE;
++      case GI_TYPE_TAG_INT32:
++          *c_long_out = arg_in->v_int32;
++          return TRUE;
++      case GI_TYPE_TAG_UINT32:
++          *c_long_out = arg_in->v_uint32;
++          return TRUE;
++      case GI_TYPE_TAG_INT64:
++          *c_long_out = arg_in->v_int64;
++          return TRUE;
++      case GI_TYPE_TAG_UINT64:
++          *c_long_out = arg_in->v_uint64;
++          return TRUE;
++      default:
++          PyErr_Format (PyExc_TypeError,
++                        "Unable to marshal %s to C long",
++                        g_type_tag_to_string(type_tag));
++          return FALSE;
++    }
++}
++
++gboolean
++gi_argument_to_gsize (GIArgument *arg_in,
++                      gsize *gsize_out,
++                      GITypeTag type_tag)
++{
++    switch (type_tag) {
++      case GI_TYPE_TAG_INT8:
++          *gsize_out = arg_in->v_int8;
++          return TRUE;
++      case GI_TYPE_TAG_UINT8:
++          *gsize_out = arg_in->v_uint8;
++          return TRUE;
++      case GI_TYPE_TAG_INT16:
++          *gsize_out = arg_in->v_int16;
++          return TRUE;
++      case GI_TYPE_TAG_UINT16:
++          *gsize_out = arg_in->v_uint16;
++          return TRUE;
++      case GI_TYPE_TAG_INT32:
++          *gsize_out = arg_in->v_int32;
++          return TRUE;
++      case GI_TYPE_TAG_UINT32:
++          *gsize_out = arg_in->v_uint32;
++          return TRUE;
++      case GI_TYPE_TAG_INT64:
++          *gsize_out = arg_in->v_int64;
++          return TRUE;
++      case GI_TYPE_TAG_UINT64:
++          *gsize_out = arg_in->v_uint64;
++          return TRUE;
++      default:
++          PyErr_Format (PyExc_TypeError,
++                        "Unable to marshal %s to gsize",
++                        g_type_tag_to_string(type_tag));
++          return FALSE;
++    }
++}
++
++
+ PyObject *
+ _pygi_marshal_to_py_void (PyGIInvokeState   *state,
+                           PyGICallableCache *callable_cache,
+@@ -284,7 +361,12 @@ _pygi_marshal_to_py_array (PyGIInvokeSta
+             }
+         } else {
+             GIArgument *len_arg = state->args[seq_cache->len_arg_index];
+-            len = len_arg->v_long;
++
++            if (!gi_argument_to_gsize (len_arg,
++                                       &len,
++                                       callable_cache->args_cache[seq_cache->len_arg_index]->type_tag)) {
++                return NULL;
++            }
+         }
+ 
+         array_ = g_array_new (FALSE,
+@@ -664,11 +746,21 @@ _pygi_marshal_to_py_interface_enum (PyGI
+ {
+     PyObject *py_obj = NULL;
+     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
++    GIBaseInfo *interface;
++    long c_long;
++
++    interface = g_type_info_get_interface (arg_cache->type_info);
++    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
++
++    if (!gi_argument_to_c_long(arg, &c_long,
++                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
++        return NULL;
++    }
+ 
+     if (iface_cache->g_type == G_TYPE_NONE) {
+-        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", arg->v_long);
++        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
+     } else {
+-        py_obj = pyg_enum_from_gtype (iface_cache->g_type, arg->v_long);
++        py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
+     }
+     return py_obj;
+ }
+@@ -681,6 +773,16 @@ _pygi_marshal_to_py_interface_flags (PyG
+ {
+     PyObject *py_obj = NULL;
+     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
++    GIBaseInfo *interface;
++    long c_long;
++
++    interface = g_type_info_get_interface (arg_cache->type_info);
++    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
++
++    if (!gi_argument_to_c_long(arg, &c_long,
++                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
++        return NULL;
++    }
+ 
+     if (iface_cache->g_type == G_TYPE_NONE) {
+         /* An enum with a GType of None is an enum without GType */
+@@ -692,18 +794,18 @@ _pygi_marshal_to_py_interface_flags (PyG
+             return NULL;
+ 
+         py_args = PyTuple_New (1);
+-        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_long)) != 0) {
++        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
+             Py_DECREF (py_args);
+             Py_DECREF (py_type);
+             return NULL;
+         }
+ 
+-        py_obj = PyObject_CallFunction (py_type, "l", arg->v_long);
++        py_obj = PyObject_CallFunction (py_type, "l", c_long);
+ 
+         Py_DECREF (py_args);
+         Py_DECREF (py_type);
+     } else {
+-        py_obj = pyg_flags_from_gtype (iface_cache->g_type, arg->v_long);
++        py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
+     }
+ 
+     return py_obj;
+Index: pygobject-3.2.2/gi/pygi-argument.c
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-argument.c
++++ pygobject-3.2.2/gi/pygi-argument.c
+@@ -1122,7 +1122,7 @@ array_success:
+                         break;
+                     }
+ 
+-                    arg.v_long = PYGLIB_PyLong_AsLong (int_);
++                    arg.v_int = PYGLIB_PyLong_AsLong (int_);
+ 
+                     Py_DECREF (int_);
+ 
+@@ -1644,21 +1644,21 @@ _pygi_argument_to_object (GIArgument  *a
+                             return NULL;
+ 
+                         py_args = PyTuple_New (1);
+-                        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_long)) != 0) {
++                        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_int)) != 0) {
+                             Py_DECREF (py_args);
+                             Py_DECREF (py_type);
+                             return NULL;
+                         }
+ 
+-                        object = PyObject_CallFunction (py_type, "l", arg->v_long);
++                        object = PyObject_CallFunction (py_type, "i", arg->v_int);
+ 
+                         Py_DECREF (py_args);
+                         Py_DECREF (py_type);
+ 
+                     } else if (info_type == GI_INFO_TYPE_ENUM) {
+-                        object = pyg_enum_from_gtype (type, arg->v_long);
++                        object = pyg_enum_from_gtype (type, arg->v_int);
+                     } else {
+-                        object = pyg_flags_from_gtype (type, arg->v_long);
++                        object = pyg_flags_from_gtype (type, arg->v_int);
+                     }
+ 
+                     break;
+Index: pygobject-3.2.2/gi/pygi-closure.c
+===================================================================
+--- pygobject-3.2.2.orig/gi/pygi-closure.c
++++ pygobject-3.2.2/gi/pygi-closure.c
+@@ -28,6 +28,57 @@
+ static GSList* async_free_list;
+ 
+ static void
++_pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object,
++                                            GITypeInfo *type_info,
++                                            GITransfer transfer)
++{
++    GIArgument arg = _pygi_argument_from_object (object, type_info, transfer);
++    GITypeTag type_tag = g_type_info_get_tag (type_info);
++
++    if (retval == NULL)
++        return;
++
++    switch (type_tag) {
++        case GI_TYPE_TAG_BOOLEAN:
++           *((ffi_sarg *) retval) = arg.v_boolean;
++           break;
++        case GI_TYPE_TAG_INT8:
++           *((ffi_sarg *) retval) = arg.v_int8;
++           break;
++        case GI_TYPE_TAG_UINT8:
++           *((ffi_arg *) retval) = arg.v_uint8;
++           break;
++        case GI_TYPE_TAG_INT16:
++           *((ffi_sarg *) retval) = arg.v_int16;
++           break;
++        case GI_TYPE_TAG_UINT16:
++           *((ffi_arg *) retval) = arg.v_uint16;
++           break;
++        case GI_TYPE_TAG_INT32:
++           *((ffi_sarg *) retval) = arg.v_int32;
++           break;
++        case GI_TYPE_TAG_UINT32:
++           *((ffi_arg *) retval) = arg.v_uint32;
++           break;
++        case GI_TYPE_TAG_INT64:
++           *((ffi_sarg *) retval) = arg.v_int64;
++           break;
++        case GI_TYPE_TAG_UINT64:
++           *((ffi_arg *) retval) = arg.v_uint64;
++           break;
++        case GI_TYPE_TAG_FLOAT:
++           *((gfloat *) retval) = arg.v_float;
++           break;
++        case GI_TYPE_TAG_DOUBLE:
++           *((gdouble *) retval) = arg.v_double;
++           break;
++        default:
++           *((GIArgument *) retval) = arg;
++           break;
++      }
++}
++
++static void
+ _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg, PyObject *object,
+                                             GITypeInfo *type_info,
+                                             GITransfer transfer)
+@@ -278,10 +329,10 @@ _pygi_closure_set_out_arguments (GICalla
+         GITransfer transfer = g_callable_info_get_caller_owns (callable_info);
+         if (PyTuple_Check (py_retval)) {
+             PyObject *item = PyTuple_GET_ITEM (py_retval, 0);
+-            _pygi_closure_assign_pyobj_to_out_argument (resp, item,
++            _pygi_closure_assign_pyobj_to_retval (resp, item,
+                 return_type_info, transfer);
+         } else {
+-            _pygi_closure_assign_pyobj_to_out_argument (resp, py_retval,
++            _pygi_closure_assign_pyobj_to_retval (resp, py_retval,
+                 return_type_info, transfer);
+         }
+         i_py_retval++;
diff --git a/fix-list-marshalling-on-big-endian-machines.patch b/fix-list-marshalling-on-big-endian-machines.patch
new file mode 100644
index 0000000..966573f
--- /dev/null
+++ b/fix-list-marshalling-on-big-endian-machines.patch
@@ -0,0 +1,185 @@
+From 770e6abfd5bc5dad7d5f56a18f1ef63f9754ada9 Mon Sep 17 00:00:00 2001
+From: Martin Pitt <martinpitt at gnome.org>
+Date: Fri, 03 Aug 2012 04:45:48 +0000
+Subject: Fix list marshalling on big-endian machines
+
+On big endian machines we cannot simply set e. g. GIArgument.v_int8 and expect
+GIArgument.v_pointer to be a correct representation. This needs to use
+GINT_TO_POINTER/GPOINTER_TO_INT properly, so use the already existing
+_pygi_hash_pointer_to_arg()/_pygi_arg_to_hash_pointer() methods in marshalling
+to and from GList and GSList, and handle int8 and int16 as well.
+
+Part of porting pygobject to ppc64:
+https://bugzilla.redhat.com/show_bug.cgi?id=842880
+https://bugzilla.gnome.org/show_bug.cgi?id=680693
+---
+diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
+index 26c08c9..5437e33 100644
+--- a/gi/pygi-marshal-from-py.c
++++ b/gi/pygi-marshal-from-py.c
+@@ -736,6 +736,33 @@ _pygi_marshal_from_py_filename (PyGIInvokeState   *state,
+     return TRUE;
+ }
+ 
++static gpointer
++_pygi_arg_to_hash_pointer (const GIArgument *arg,
++                           GITypeTag        type_tag)
++{
++    switch (type_tag) {
++        case GI_TYPE_TAG_INT8:
++            return GINT_TO_POINTER(arg->v_int8);
++        case GI_TYPE_TAG_UINT8:
++            return GINT_TO_POINTER(arg->v_uint8);
++        case GI_TYPE_TAG_INT16:
++            return GINT_TO_POINTER(arg->v_int16);
++        case GI_TYPE_TAG_UINT16:
++            return GINT_TO_POINTER(arg->v_uint16);
++        case GI_TYPE_TAG_INT32:
++            return GINT_TO_POINTER(arg->v_int32);
++        case GI_TYPE_TAG_UINT32:
++            return GINT_TO_POINTER(arg->v_uint32);
++        case GI_TYPE_TAG_UTF8:
++        case GI_TYPE_TAG_FILENAME:
++        case GI_TYPE_TAG_INTERFACE:
++            return arg->v_pointer;
++        default:
++            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
++            return arg->v_pointer;
++    }
++}
++
+ gboolean
+ _pygi_marshal_from_py_array (PyGIInvokeState   *state,
+                              PyGICallableCache *callable_cache,
+@@ -985,7 +1012,7 @@ _pygi_marshal_from_py_glist (PyGIInvokeState   *state,
+                                  &item))
+             goto err;
+ 
+-        list_ = g_list_prepend (list_, item.v_pointer);
++        list_ = g_list_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
+         continue;
+ err:
+         /* FIXME: clean up list
+@@ -1052,7 +1079,7 @@ _pygi_marshal_from_py_gslist (PyGIInvokeState   *state,
+                             &item))
+             goto err;
+ 
+-        list_ = g_slist_prepend (list_, item.v_pointer);
++        list_ = g_slist_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
+         continue;
+ err:
+         /* FIXME: Clean up list
+@@ -1070,23 +1097,6 @@ err:
+     return TRUE;
+ }
+ 
+-static gpointer
+-_pygi_arg_to_hash_pointer (const GIArgument *arg,
+-                           GITypeTag        type_tag)
+-{
+-    switch (type_tag) {
+-        case GI_TYPE_TAG_INT32:
+-            return GINT_TO_POINTER(arg->v_int32);
+-        case GI_TYPE_TAG_UTF8:
+-        case GI_TYPE_TAG_FILENAME:
+-        case GI_TYPE_TAG_INTERFACE:
+-            return arg->v_pointer;
+-        default:
+-            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
+-            return arg->v_pointer;
+-    }
+-}
+-
+ gboolean
+ _pygi_marshal_from_py_ghash (PyGIInvokeState   *state,
+                              PyGICallableCache *callable_cache,
+diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
+index 3af443d..b906aa2 100644
+--- a/gi/pygi-marshal-to-py.c
++++ b/gi/pygi-marshal-to-py.c
+@@ -415,6 +415,29 @@ err:
+     return NULL;
+ }
+ 
++static void
++_pygi_hash_pointer_to_arg (GIArgument *arg,
++                           GITypeTag  type_tag)
++{
++    switch (type_tag) {
++        case GI_TYPE_TAG_INT8:
++            arg->v_int8 = GPOINTER_TO_INT(arg->v_pointer);
++            break;
++        case GI_TYPE_TAG_INT16:
++            arg->v_int16 = GPOINTER_TO_INT(arg->v_pointer);
++            break;
++        case GI_TYPE_TAG_INT32:
++            arg->v_int32 = GPOINTER_TO_INT(arg->v_pointer);
++            break;
++        case GI_TYPE_TAG_UTF8:
++        case GI_TYPE_TAG_FILENAME:
++        case GI_TYPE_TAG_INTERFACE:
++            break;
++        default:
++            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
++    }
++}
++
+ PyObject *
+ _pygi_marshal_to_py_glist (PyGIInvokeState   *state,
+                            PyGICallableCache *callable_cache,
+@@ -446,10 +469,11 @@ _pygi_marshal_to_py_glist (PyGIInvokeState   *state,
+         PyObject *py_item;
+ 
+         item_arg.v_pointer = list_->data;
+-        py_item = item_to_py_marshaller ( state,
+-                                        callable_cache,
+-                                        item_arg_cache,
+-                                       &item_arg);
++        _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
++        py_item = item_to_py_marshaller (state,
++                                         callable_cache,
++                                         item_arg_cache,
++                                         &item_arg);
+ 
+         if (py_item == NULL) {
+             Py_CLEAR (py_obj);
+@@ -494,10 +518,11 @@ _pygi_marshal_to_py_gslist (PyGIInvokeState   *state,
+         PyObject *py_item;
+ 
+         item_arg.v_pointer = list_->data;
+-        py_item = item_to_py_marshaller ( state,
++        _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
++        py_item = item_to_py_marshaller (state,
+                                         callable_cache,
+                                         item_arg_cache,
+-                                       &item_arg);
++                                        &item_arg);
+ 
+         if (py_item == NULL) {
+             Py_CLEAR (py_obj);
+@@ -511,23 +536,6 @@ _pygi_marshal_to_py_gslist (PyGIInvokeState   *state,
+     return py_obj;
+ }
+ 
+-static void
+-_pygi_hash_pointer_to_arg (GIArgument *arg,
+-                           GITypeTag  type_tag)
+-{
+-    switch (type_tag) {
+-        case GI_TYPE_TAG_INT32:
+-            arg->v_int32 = GPOINTER_TO_INT(arg->v_pointer);
+-            break;
+-        case GI_TYPE_TAG_UTF8:
+-        case GI_TYPE_TAG_FILENAME:
+-        case GI_TYPE_TAG_INTERFACE:
+-            break;
+-        default:
+-            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
+-    }
+-}
+-
+ PyObject *
+ _pygi_marshal_to_py_ghash (PyGIInvokeState   *state,
+                            PyGICallableCache *callable_cache,
+--
+cgit v0.9.0.2
diff --git a/pygobject3.spec b/pygobject3.spec
index 1f43abd..6c52a5f 100644
--- a/pygobject3.spec
+++ b/pygobject3.spec
@@ -22,7 +22,7 @@
 
 Name: pygobject3
 Version: 3.3.4
-Release: 5%{?dist}
+Release: 6%{?dist}
 License: LGPLv2+ and MIT
 Group: Development/Languages
 Summary: Python 2 bindings for GObject Introspection
@@ -66,6 +66,18 @@ Patch1: ignore-more-pep8-errors.patch
 # Not yet sent upstream
 Patch2: pygobject-3.3.4-known-failures.patch
 
+# Fix various endianness issues that broke things on big-endian 64 bit boxes
+# (rhbz#841596; attachment 603090):
+Patch3: endianness-fixes.patch
+
+# Cherrypick fix from upstream (in 3.3.5 onwards; rhbz#842880):
+Patch4: fix-list-marshalling-on-big-endian-machines.patch
+
+# Add regression test for rhbz#842880
+# Not yet sent upstream:
+Patch5: test-list-marshalling.patch
+
+
 ### Build Dependencies ###
 
 BuildRequires: glib2-devel >= %{glib2_version}
@@ -134,6 +146,9 @@ for use in Python 3 programs.
 %setup -q -n pygobject-%{version}
 %patch1 -p1 -b .ignore-more-pep8-errors
 %patch2 -p1 -b .known-failures
+%patch3 -p1 -b .endianness-fixes
+%patch4 -p1 -b .fix-list-marshalling-on-big-endian-machines
+%patch5 -p1 -b .test-list-marshalling
 
 %if 0%{?with_python3}
 rm -rf %{py3dir}
@@ -230,6 +245,9 @@ xvfb-run make DESTDIR=$RPM_BUILD_ROOT check %{verbosity}
 %endif # with_python3
 
 %changelog
+* Thu Aug  9 2012 David Malcolm <dmalcolm at redhat.com> - 3.3.4-6
+- fix issues on big-endian 64-bit machines (rhbz#841596, rhbz#842880)
+
 * Thu Aug  9 2012 David Malcolm <dmalcolm at redhat.com> - 3.3.4-5
 - use xvfb-run in selftests; update known failures
 
diff --git a/test-list-marshalling.patch b/test-list-marshalling.patch
new file mode 100644
index 0000000..4fa5dde
--- /dev/null
+++ b/test-list-marshalling.patch
@@ -0,0 +1,15 @@
+diff -up pygobject-3.3.4/tests/test_overrides.py.test-list-marshalling pygobject-3.3.4/tests/test_overrides.py
+--- pygobject-3.3.4/tests/test_overrides.py.test-list-marshalling	2012-07-04 02:42:46.000000000 -0400
++++ pygobject-3.3.4/tests/test_overrides.py	2012-08-09 14:54:26.783741969 -0400
+@@ -1981,6 +1981,11 @@ class TestGtk(unittest.TestCase):
+         self.assertEqual(viewport.props.vadjustment, vadjustment)
+         self.assertEqual(viewport.props.hadjustment, hadjustment)
+ 
++    def test_rhbz842880(self):
++        # Regression test for https://bugzilla.redhat.com/show_bug.cgi?id=842880
++        store = Gtk.ListStore(int, int)
++        store.append([1, 2])
++
+ 
+ class TestGio(unittest.TestCase):
+     def setUp(self):


More information about the scm-commits mailing list