[gjs/gnome-3-36] arg: Fix GList and GHashTable marshalling on 64-bit big-endian
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-3-36] arg: Fix GList and GHashTable marshalling on 64-bit big-endian
- Date: Sun, 19 Apr 2020 18:25:03 +0000 (UTC)
commit 3f0f834a49486f81b5b3abb70209da797a55d1f9
Author: Philip Chimento <philip chimento gmail com>
Date: Sat Apr 4 19:54:21 2020 -0700
arg: Fix GList and GHashTable marshalling on 64-bit big-endian
It is not correct to simply write to arg->v_pointer and read out a
different member of the GIArgument union, or vice-versa. We were doing
this when stuffing integers into pointers for storage in a GList,
GSList, or GHashTable. In the case of 32-bit ints, this would read out
the wrong half of the pointer on big-endian 64-bit architectures.
Closes: #309
gi/arg.cpp | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 113 insertions(+), 8 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 04bd3c8c..530bbd2d 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -278,6 +278,103 @@ static GITypeTag _g_type_info_get_storage_type(GITypeInfo* info) {
return type_tag;
}
+/* FIXME: This should be added to gobject-introspection */
+static void _g_type_info_argument_from_hash_pointer(GITypeInfo* info,
+ void* hash_pointer,
+ GIArgument* arg) {
+ GITypeTag type_tag = _g_type_info_get_storage_type(info);
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ arg->v_boolean = !!GPOINTER_TO_INT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_INT8:
+ arg->v_int8 = (gint8)GPOINTER_TO_INT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ arg->v_uint8 = (guint8)GPOINTER_TO_UINT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_INT16:
+ arg->v_int16 = (gint16)GPOINTER_TO_INT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ arg->v_uint16 = (guint16)GPOINTER_TO_UINT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_INT32:
+ arg->v_int32 = (gint32)GPOINTER_TO_INT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UNICHAR:
+ arg->v_uint32 = (guint32)GPOINTER_TO_UINT(hash_pointer);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ arg->v_size = GPOINTER_TO_SIZE(hash_pointer);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ arg->v_pointer = hash_pointer;
+ break;
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ default:
+ g_critical("Unsupported type for pointer-stuffing: %s",
+ g_type_tag_to_string(type_tag));
+ arg->v_pointer = hash_pointer;
+ }
+}
+
+/* FIXME: This should be added to gobject-introspection */
+GJS_USE
+static void* _g_type_info_hash_pointer_from_argument(GITypeInfo* info,
+ GIArgument* arg) {
+ GITypeTag type_tag = _g_type_info_get_storage_type(info);
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ return GINT_TO_POINTER(arg->v_boolean);
+ case GI_TYPE_TAG_INT8:
+ return GINT_TO_POINTER(arg->v_int8);
+ case GI_TYPE_TAG_UINT8:
+ return GUINT_TO_POINTER(arg->v_uint8);
+ case GI_TYPE_TAG_INT16:
+ return GINT_TO_POINTER(arg->v_int16);
+ case GI_TYPE_TAG_UINT16:
+ return GUINT_TO_POINTER(arg->v_uint16);
+ case GI_TYPE_TAG_INT32:
+ return GINT_TO_POINTER(arg->v_int32);
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UNICHAR:
+ return GUINT_TO_POINTER(arg->v_uint32);
+ case GI_TYPE_TAG_GTYPE:
+ return GSIZE_TO_POINTER(arg->v_size);
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ return arg->v_pointer;
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ default:
+ g_critical("Unsupported type for pointer-stuffing: %s",
+ g_type_tag_to_string(type_tag));
+ return arg->v_pointer;
+ }
+}
+
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_array_to_g_list(JSContext *context,
@@ -338,12 +435,15 @@ gjs_array_to_g_list(JSContext *context,
return false;
}
+ void* hash_pointer =
+ _g_type_info_hash_pointer_from_argument(param_info, &elem_arg);
+
if (list_type == GI_TYPE_TAG_GLIST) {
/* GList */
- list = g_list_prepend(list, elem_arg.v_pointer);
+ list = g_list_prepend(list, hash_pointer);
} else {
/* GSList */
- slist = g_slist_prepend(slist, elem_arg.v_pointer);
+ slist = g_slist_prepend(slist, hash_pointer);
}
}
@@ -582,8 +682,9 @@ gjs_object_to_g_hash(JSContext *context,
*heap_val = val_arg.v_double;
val_ptr = heap_val;
} else {
- /* Other types are simply stuffed inside v_pointer */
- val_ptr = val_arg.v_pointer;
+ // Other types are simply stuffed inside the pointer
+ val_ptr = _g_type_info_hash_pointer_from_argument(val_param_info,
+ &val_arg);
}
g_hash_table_insert(result, key_ptr, val_ptr);
@@ -2242,7 +2343,8 @@ gjs_array_from_g_list (JSContext *context,
i = 0;
if (list_tag == GI_TYPE_TAG_GLIST) {
for ( ; list != NULL; list = list->next) {
- arg.v_pointer = list->data;
+ _g_type_info_argument_from_hash_pointer(param_info, list->data,
+ &arg);
if (!elems.growBy(1)) {
JS_ReportOutOfMemory(context);
return false;
@@ -2255,7 +2357,8 @@ gjs_array_from_g_list (JSContext *context,
}
} else {
for ( ; slist != NULL; slist = slist->next) {
- arg.v_pointer = slist->data;
+ _g_type_info_argument_from_hash_pointer(param_info, slist->data,
+ &arg);
if (!elems.growBy(1)) {
JS_ReportOutOfMemory(context);
return false;
@@ -2646,8 +2749,8 @@ gjs_object_from_g_hash (JSContext *context,
JS::RootedString keystr(context);
g_hash_table_iter_init(&iter, hash);
- while (g_hash_table_iter_next
- (&iter, &keyarg.v_pointer, &valarg.v_pointer)) {
+ void* val_pointer;
+ while (g_hash_table_iter_next(&iter, &keyarg.v_pointer, &val_pointer)) {
if (!gjs_value_from_g_argument(context, &keyjs,
key_param_info, &keyarg,
true))
@@ -2661,6 +2764,8 @@ gjs_object_from_g_hash (JSContext *context,
if (!keyutf8)
return false;
+ _g_type_info_argument_from_hash_pointer(val_param_info, val_pointer,
+ &valarg);
if (!gjs_value_from_g_argument(context, &valjs,
val_param_info, &valarg,
true))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]