[perl-Glib-Object-Introspection/ppc64-fixes: 6/6] Fix an endian-ness bug with the array length marshalling



commit 70bc701b2875e285e8fe86571121427b03c73804
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Sun Sep 7 19:44:04 2014 +0200

    Fix an endian-ness bug with the array length marshalling
    
    We were always accessing array length args as gsize, but on big-endian systems
    this does not work when the actual type of the arg is bigger than gsize.  This
    occurred on ppc64.
    
    https://rt.cpan.org/Ticket/Display.html?id=98463

 gperl-i11n-invoke-c.c      |   17 +++++++++++++----
 gperl-i11n-marshal-array.c |   10 +++++++---
 2 files changed, 20 insertions(+), 7 deletions(-)
---
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 8b5c2c4..3ace75c 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -10,6 +10,8 @@ static void _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
 static void _clear_c_invocation_info (GPerlI11nCInvocationInfo *iinfo);
 static void _check_n_args (GPerlI11nCInvocationInfo *iinfo);
 static void _handle_automatic_arg (guint pos,
+                                   GIArgInfo * arg_info,
+                                   GITypeInfo * arg_type,
                                    GIArgument * arg,
                                    GPerlI11nCInvocationInfo * invocation_info);
 static gpointer _allocate_out_mem (GITypeInfo *arg_type);
@@ -150,15 +152,17 @@ invoke_c_code (GICallableInfo *info,
        /* do another pass to handle automatic args */
        for (i = 0 ; i < iinfo.base.n_args ; i++) {
                GIArgInfo * arg_info;
+               GITypeInfo * arg_type;
                if (!iinfo.is_automatic_arg[i])
                        continue;
                arg_info = iinfo.base.arg_infos[i];
+               arg_type = iinfo.base.arg_types[i];
                switch (g_arg_info_get_direction (arg_info)) {
                    case GI_DIRECTION_IN:
-                       _handle_automatic_arg (i, &iinfo.in_args[i], &iinfo);
+                       _handle_automatic_arg (i, arg_info, arg_type, &iinfo.in_args[i], &iinfo);
                        break;
                    case GI_DIRECTION_INOUT:
-                       _handle_automatic_arg (i, &iinfo.base.aux_args[i], &iinfo);
+                       _handle_automatic_arg (i, arg_info, arg_type, &iinfo.base.aux_args[i], &iinfo);
                        break;
                    case GI_DIRECTION_OUT:
                        /* handled later */
@@ -505,6 +509,8 @@ _check_n_args (GPerlI11nCInvocationInfo *iinfo)
 
 static void
 _handle_automatic_arg (guint pos,
+                       GIArgInfo * arg_info,
+                       GITypeInfo * arg_type,
                        GIArgument * arg,
                        GPerlI11nCInvocationInfo * invocation_info)
 {
@@ -514,10 +520,13 @@ _handle_automatic_arg (guint pos,
        for (l = invocation_info->base.array_infos; l != NULL; l = l->next) {
                GPerlI11nArrayInfo *ainfo = l->data;
                if (((gint) pos) == ainfo->length_pos) {
+                       SV *conversion_sv;
                        dwarn ("  setting automatic arg %d (array length) to %"G_GSIZE_FORMAT"\n",
                               pos, ainfo->length);
-                       /* FIXME: Is it OK to always use v_size here? */
-                       arg->v_size = ainfo->length;
+                       conversion_sv = newSVuv (ainfo->length);
+                       sv_to_arg (conversion_sv, arg, arg_info, arg_type,
+                                  GI_TRANSFER_NOTHING, FALSE, NULL);
+                       SvREFCNT_dec (conversion_sv);
                        return;
                }
        }
diff --git a/gperl-i11n-marshal-array.c b/gperl-i11n-marshal-array.c
index 017cd0d..d11d09c 100644
--- a/gperl-i11n-marshal-array.c
+++ b/gperl-i11n-marshal-array.c
@@ -42,10 +42,14 @@ array_to_sv (GITypeInfo *info,
        } else {
                length = g_type_info_get_array_fixed_size (info);
                if (length < 0) {
-                       guint length_pos = g_type_info_get_array_length (info);
+                       SV *conversion_sv;
+                       gint length_pos = g_type_info_get_array_length (info);
                        g_assert (iinfo && iinfo->aux_args);
-                       /* FIXME: Is it OK to always use v_size here? */
-                       length = iinfo->aux_args[length_pos].v_size;
+                       conversion_sv = arg_to_sv (&(iinfo->aux_args[length_pos]),
+                                                  iinfo->arg_types[length_pos],
+                                                  GI_TRANSFER_NOTHING, NULL);
+                       length = SvIV (conversion_sv);
+                       SvREFCNT_dec (conversion_sv);
                }
        }
 


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