Bug#653308: value_from_ffi_type: broken on 64bit big endian

Philipp Kern pkern at debian.org
Mon Dec 26 17:48:26 UTC 2011


Source: glib2.0
Version: 2.30.2-4
Severity: important
Tags: patch
User: debian-s390 at lists.debian.org
Usertags: s390x

gobject/gclosure.c:value_from_ffi_type in sid does conversions that are unsafe
on big endian architectures and cause breakage at least on 64bit big endian
architectures (such as s390x, sparc64 and ppc64).  For G_TYPE_BOOLEAN you'd
get the first machine word (zeros) instead of the one in the second word
(MSB first).  Hence glib-networking's testsuite broke.

This was already fixed upstream, they replaced the function with this[1]:

static void
value_from_ffi_type (GValue *gvalue, gpointer *value)
{
  ffi_arg *int_val = (ffi_arg*) value;

  switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
    {
    case G_TYPE_INT:
      g_value_set_int (gvalue, (gint) *int_val);
      break;
    case G_TYPE_FLOAT:
      g_value_set_float (gvalue, *(gfloat*)value);
      break;
    case G_TYPE_DOUBLE:
      g_value_set_double (gvalue, *(gdouble*)value);
      break;
    case G_TYPE_BOOLEAN:
      g_value_set_boolean (gvalue, (gboolean) *int_val);
      break;
    case G_TYPE_STRING:
      g_value_set_string (gvalue, *(gchar**)value);
      break;
    case G_TYPE_CHAR:
      g_value_set_schar (gvalue, (gint8) *int_val);
      break;
    case G_TYPE_UCHAR:
      g_value_set_uchar (gvalue, (guchar) *int_val);
      break;
    case G_TYPE_UINT:
      g_value_set_uint (gvalue, (guint) *int_val);
      break;
    case G_TYPE_POINTER:
      g_value_set_pointer (gvalue, *(gpointer*)value);
      break;
    case G_TYPE_LONG:
      g_value_set_long (gvalue, (glong) *int_val);
      break;
    case G_TYPE_ULONG:
      g_value_set_ulong (gvalue, (gulong) *int_val);
      break;
    case G_TYPE_INT64:
      g_value_set_int64 (gvalue, (gint64) *int_val);
      break;
    case G_TYPE_UINT64:
      g_value_set_uint64 (gvalue, (guint64) *int_val);
      break;
    case G_TYPE_BOXED:
      g_value_set_boxed (gvalue, *(gpointer*)value);
      break;
    case G_TYPE_ENUM:
      g_value_set_enum (gvalue, (gint) *int_val);
      break;
    case G_TYPE_FLAGS:
      g_value_set_flags (gvalue, (guint) *int_val);
      break;
    case G_TYPE_PARAM:
      g_value_set_param (gvalue, *(gpointer*)value);
      break;
    case G_TYPE_OBJECT:
      g_value_set_object (gvalue, *(gpointer*)value);
      break;
    default:
      g_warning ("value_from_ffi_type: Unsupported fundamental type: %s",
                g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
    }
}

At least for gboolean that looks much more sane and solves the problem.  Given
the fact that a bunch of the other cases were also problematic, I'd suggest
replacing that function with the one above.  I was told that FFI support is
pretty new, I don't know if there are more big endian issues lingering around.
The testsuite has a bunch of issues too.

If that could be fixed timely, that would be cool.  (As long as it doesn't
break anything, but the old code looked obviously wrong.)  It blocks a lot of
GNOME stuff being built on s390x, because glib-networking aborts on testsuite
failures.

Kind regards
Philipp Kern

[1] http://git.gnome.org/browse/glib/tree/gobject/gclosure.c#n1032





More information about the pkg-gnome-maintainers mailing list