gclosure: value_from_ffi_type not endian-safe
Submitted by Philipp Kern
Link to original bug (#666846)
Description
glib-networking had a testsuite failure on s390x where the boolean return value of a signal handler did not cause the signal handling to stop (using gio's accept-certificate hook). The value that was passed to the internal gclosure handling code was FALSE instead of the TRUE that the handler returned.
The culprit is gclosure's value_from_ffi_type which does the following for booleans:
case G_TYPE_BOOLEAN:
g_value_set_boolean (gvalue, *(gboolean*)value);
break;
value is a gpointer* which indeed contains 1 when dereferenced. However casting it to gboolean* truncates the value from 8 byte to 4 byte. Due to s390x being big endian you get the most significant zeros instead of the 1.
I wouldn't be surprised if the other cases of that functions fail in a similar way. Reinterpreting an 8 byte word as a 4 byte int won't work neither, for instance. You'll get the first "field" of the bigger word, which means only the most significant bits, which is not what you want. Unless I miss something that function should get endianness handling.
In this case an ugly (gboolean)(gsize)value works. In any case it needs to be a type-aware conversion on big endian architectures, not reinterpreting type casts.
Version: 2.30.x