GNOME Bugzilla – Bug 646581
A gaRRAY OF ENUMS MAY NOT BE RETURNED CORRECTLY
Last modified: 2018-01-10 20:08:11 UTC
When _pygi_argument_to_object sees an array, it fetches the size of an item and then calls memcpy to copy an item from the array into a GIArgument. It then recurses, and, if the subtype is an enum, it assumes that the GIArgument holds a long. This can cause problems on 64-bit systems for instance if the array contained ints rather than longs, since only the first four bytes of the GIArgument data were ever initialized.
Created attachment 184997 [details] [review] Proposed patch.
Comment on attachment 184997 [details] [review] Proposed patch. This looks good. Commit it to the pygobject-2-28 branch but not master. I am going to land the invoke rewrite branch soon and we do marshalling quite differently.
Comment on attachment 184997 [details] [review] Proposed patch. >From 1558a365bffe6682dfb06c6cdce514bcd04c3219 Mon Sep 17 00:00:00 2001 >From: Mike Gorse <mgorse@novell.com> >Date: Sat, 2 Apr 2011 18:45:40 -0500 >Subject: [PATCH] [gi] fetch size from an enum type > >Do not assume that an enum is returned as a long; treat it as an int if >the type indicates that its size is that of an int. > >http://bugzilla.gnome.org/show_bug.cgi?id=646581 >--- > gi/pygi-argument.c | 25 ++++++++++++++++++++++--- > 1 files changed, 22 insertions(+), 3 deletions(-) > >diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c >index 58f6fb0..c2b2a5c 100644 >--- a/gi/pygi-argument.c >+++ b/gi/pygi-argument.c >@@ -1316,6 +1316,23 @@ hash_table_release: > return arg; > } > >+static glong >+_pygi_glong_from_argument (GIArgument *arg, >+ GITypeInfo *type_info) >+{ >+ gsize item_size = _pygi_g_type_info_size (type_info); >+ >+ if (item_size == sizeof (glong)) >+ return arg->v_long; >+ else if (item_size == sizeof (gint)) >+ return arg->v_int; >+ else >+ { >+ g_warning ("pygi: unsupported item size %ld", item_size); >+ return arg->v_long; >+ } >+} >+ > PyObject * > _pygi_argument_to_object (GIArgument *arg, > GITypeInfo *type_info, >@@ -1621,24 +1638,26 @@ _pygi_argument_to_object (GIArgument *arg, > /* An enum with a GType of None is an enum without GType */ > PyObject *py_type = _pygi_type_import_by_gi_info (info); > PyObject *py_args = NULL; >+ glong val = _pygi_glong_from_argument (arg, type_info); > > if (!py_type) > 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 (val)) != 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, "l", val); > > 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); >+ glong val = _pygi_glong_from_argument (arg, type_info); >+ object = pyg_enum_from_gtype (type, val); > } else { > object = pyg_flags_from_gtype (type, arg->v_long); > } >-- >1.7.3.4 >
There is another bug in master which results in similar symptoms. And apparently I never added a test when I fixed the original bug in 2.28.
Created attachment 347571 [details] [review] patch to add a marshalling test
Created attachment 347572 [details] [review] Proposed patch. _pygi_marshal_to_py_array doesn't have any code to handle enums, so it wrongly uses the default in the switch, which treats them like pointers. I also tried to add a test. Although the test passes with the patch applied, it isn't quite right, since it prints this warning: /usr/lib64/python3.4/unittest/case.py:923: Warning: comparing different enum types: GIMarshallingTestsGEnum and PyGIMarshallingTestsEnum if seq1 == seq2: I'm not really sure what the right syntax would be.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pygobject/issues/14.