[pygobject] Fix unmarshalling of gssize
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Fix unmarshalling of gssize
- Date: Mon, 20 Aug 2012 09:29:45 +0000 (UTC)
commit 266d37719bb54e6f04d23ff21bcceb9514e20ff2
Author: David Malcolm <dmalcolm redhat com>
Date: Mon Aug 20 11:27:52 2012 +0200
Fix unmarshalling of gssize
Do not assume that the v_int union member always corresponds to a gssize. This
is not true on big-endian 64 bit machines like ppc64, so add a new
gi_argument_to_gssize() and use it properly.
https://bugzilla.gnome.org/show_bug.cgi?id=680693
https://bugzilla.redhat.com/show_bug.cgi?id=842880
gi/pygi-argument.c | 53 +++++++++++++++++++++++++++++++++++++++++++--
gi/pygi-argument.h | 1 +
gi/pygi-closure.c | 2 +-
gi/pygi-info.c | 4 +-
gi/pygi-signal-closure.c | 2 +-
5 files changed, 55 insertions(+), 7 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index db97a86..b7cab1a 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -31,6 +31,44 @@
#include <pyglib-python-compat.h>
#include <pyglib.h>
+static gboolean
+gi_argument_to_gssize (GIArgument *arg_in,
+ GITypeTag type_tag,
+ gssize *gssize_out)
+{
+ switch (type_tag) {
+ case GI_TYPE_TAG_INT8:
+ *gssize_out = arg_in->v_int8;
+ return TRUE;
+ case GI_TYPE_TAG_UINT8:
+ *gssize_out = arg_in->v_uint8;
+ return TRUE;
+ case GI_TYPE_TAG_INT16:
+ *gssize_out = arg_in->v_int16;
+ return TRUE;
+ case GI_TYPE_TAG_UINT16:
+ *gssize_out = arg_in->v_uint16;
+ return TRUE;
+ case GI_TYPE_TAG_INT32:
+ *gssize_out = arg_in->v_int32;
+ return TRUE;
+ case GI_TYPE_TAG_UINT32:
+ *gssize_out = arg_in->v_uint32;
+ return TRUE;
+ case GI_TYPE_TAG_INT64:
+ *gssize_out = arg_in->v_int64;
+ return TRUE;
+ case GI_TYPE_TAG_UINT64:
+ *gssize_out = arg_in->v_uint64;
+ return TRUE;
+ default:
+ PyErr_Format (PyExc_TypeError,
+ "Unable to marshal %s to gssize",
+ g_type_tag_to_string(type_tag));
+ return FALSE;
+ }
+}
+
void
_pygi_hash_pointer_to_arg (GIArgument *arg,
GITypeTag type_tag)
@@ -708,6 +746,7 @@ check_number_release:
* @arg: The argument to convert
* @args: Arguments to method invocation, possibly contaning the array length.
* Set to NULL if this is not for a method call
+ * @callable_info: Info on the callable, if this a method call; otherwise NULL
* @type_info: The type info for @arg
* @out_free_array: A return location for a gboolean that indicates whether
* or not the wrapped GArray should be freed
@@ -725,6 +764,7 @@ check_number_release:
GArray *
_pygi_argument_to_array (GIArgument *arg,
GIArgument *args[],
+ GICallableInfo *callable_info,
GITypeInfo *type_info,
gboolean *out_free_array)
{
@@ -762,12 +802,19 @@ _pygi_argument_to_array (GIArgument *arg,
return g_array;
}
gint length_arg_pos;
+ GIArgInfo *length_arg_info;
+ GITypeInfo *length_type_info;
length_arg_pos = g_type_info_get_array_length (type_info);
g_assert (length_arg_pos >= 0);
-
- /* FIXME: Take into account the type of the length argument */
- length = args[length_arg_pos]->v_int;
+ g_assert (callable_info);
+ length_arg_info = g_callable_info_get_arg (callable_info, length_arg_pos);
+ length_type_info = g_arg_info_get_type (length_arg_info);
+ if (!gi_argument_to_gssize (args[length_arg_pos],
+ g_type_info_get_tag (length_type_info),
+ &length)) {
+ return NULL;
+ }
}
}
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
index 32f263b..a1420ee 100644
--- a/gi/pygi-argument.h
+++ b/gi/pygi-argument.h
@@ -50,6 +50,7 @@ gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
GArray* _pygi_argument_to_array (GIArgument *arg,
GIArgument *args[],
+ GICallableInfo *callable_info,
GITypeInfo *type_info,
gboolean *out_free_array);
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index bec0bc4..f6f5c51 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -351,7 +351,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
if (g_type_info_get_tag (arg_type) == GI_TYPE_TAG_ARRAY)
arg->v_pointer = _pygi_argument_to_array (arg, (GIArgument **) args,
- arg_type, &free_array);
+ callable_info, arg_type, &free_array);
value = _pygi_argument_to_object (arg, arg_type, transfer);
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 9f92cd3..3ca5c8f 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -1157,7 +1157,7 @@ _wrap_g_constant_info_get_value (PyGIBaseInfo *self)
type_info = g_constant_info_get_type ( (GIConstantInfo *) self->info);
if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ARRAY) {
- value.v_pointer = _pygi_argument_to_array (&value, NULL,
+ value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL,
type_info, &free_array);
}
@@ -1290,7 +1290,7 @@ _wrap_g_field_info_get_value (PyGIBaseInfo *self,
}
if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) {
- value.v_pointer = _pygi_argument_to_array (&value, NULL,
+ value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL,
field_type_info, &free_array);
}
diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c
index 4e9dcb5..83f9a41 100644
--- a/gi/pygi-signal-closure.c
+++ b/gi/pygi-signal-closure.c
@@ -154,7 +154,7 @@ pygi_signal_closure_marshal(GClosure *closure,
arg = _pygi_argument_from_g_value(¶m_values[i], &type_info);
if (g_type_info_get_tag (&type_info) == GI_TYPE_TAG_ARRAY) {
- arg.v_pointer = _pygi_argument_to_array (&arg, NULL,
+ arg.v_pointer = _pygi_argument_to_array (&arg, NULL, NULL,
&type_info, &free_array);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]