After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 312485 - inconsistent handling of enum GValues
inconsistent handling of enum GValues
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
2.6.x
Other All
: Normal critical
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2005-08-03 17:40 UTC by Michael Lorenz
Modified: 2011-02-18 16:11 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
a patch (20.31 KB, patch)
2005-08-09 05:04 UTC, Matthias Clasen
none Details | Review
updated patch (19.85 KB, patch)
2005-08-09 13:50 UTC, Matthias Clasen
none Details | Review

Description Michael Lorenz 2005-08-03 17:40:29 UTC
Please describe the problem:
Everything on glib2 and gtk2 seems to treat enum GValues/GParams and so on as  
long, except gobject/gparamconvert.c which treats them as int. On  
NetBSD/sparc64 sizeof(long) is 8 while sizeof(int) is 4 which leads to all  
enums getting converted to 0 because all converter functions would only access  
the upper 32 bits instead of the whole thing 

Steps to reproduce:
Compile any application that uses gtk2's text editor control on NetBSD/sparc64 
and try to edit any text  

Actual results:
cursor keys don't work as expected - they all map to cursor left/right  

Expected results:
cursor up/down should move the cursor up/down for starters 

Does this happen every time?
yes 

Other information:
I'm sure there are other problems I just didn't notice - the bug should lead to   
ALL enums being 'converted' to 0 and the other way around would lead to  
garbage because the information would end up in the wrong halfword while 
leaving the lower 32bit alone.
Comment 1 Owen Taylor 2005-08-04 17:31:12 UTC
You need to be a more specific here.

Please provide specific line number references or, better, a tested patch.

GTK+ does get testing in 64-bit big endian environments, so the problems
may be compiler dependent or similar.
Comment 2 Michael Lorenz 2005-08-04 18:07:38 UTC
The problem is definitely not compiler dependent and testing in a little-endian 
64bit environment won't trigger the bug. 
 
The problem is that almost everyone uses v_long or v_ulong to access a GValue 
with g_type==G_TYPE_ENUM - see genums.c: 
 
gint 
g_value_get_enum (const GValue *value) 
{ 
  g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0); 
  return value->data[0].v_long; 
} 
 
only the functions in gvaluetransform.c use v_uint. In a big-endian 64bit 
environment that leads to data loss because it accesses the upper half of 
v_long. 
Comment 3 Matthias Clasen 2005-08-05 14:00:55 UTC
Can you provide a small, selfcontained testcase ? 
Maybe our tests (which do get run on ppc64) don't cover this case.
Comment 4 Michael Lorenz 2005-08-05 14:35:44 UTC
Use something like gaim, bluefish, gedit. Enter some text and check what the   
up/down cursor keys do - if the cursor moves left/right instead of up/down you   
have the bug. The 'Multiple Views' test in gtk-demo should have it too, just   
try to move the cursor around with the keyboard.   
This happens because the resp. message sent to the text view consists of a  
command code ( 'move cursor horizontally', 'page up/down' ), a direction and  
some flag. The command is an enum and 0 is 'move cursor horizontally' so all  
cursor movement commands end up as cursor left or right.  
Comment 5 Matthias Clasen 2005-08-05 14:39:02 UTC
We won't include gaim, bluefish or gedit in our testsuite...
Comment 6 Michael Lorenz 2005-08-05 16:14:53 UTC
Did you even look at the problem at all? Anyway, here's a program that 
demonstrates it: 
   
#include <glib.h> 
#include <glib-object.h> 
 
int main() 
{ 
 GValue foo = { 0, }, bar = { 0, }; 
 GType type; 
 GEnumValue values[] = { {0,"0","0"}, {1,"1","1"}}; 
  
 g_type_init_with_debug_flags(0); 
  
 type = g_enum_register_static("bork", values); 
  
 g_value_init(&foo, type); 
 g_value_init(&bar, G_TYPE_LONG); 
 g_value_set_enum(&foo, 1); 
 g_value_transform(&foo, &bar); 
 printf("before: %d after: %d\n", 1, g_value_get_long(&bar)); 
 return 0; 
} 
 
On a 64bit big-endian box ( like my Ultra10 running NetBSD/sparc64 ) bar will 
contain 0, on a 32bit box ( checked it on NetBSD/macppc ) it correctly contains 
1. 
Comment 7 Matthias Clasen 2005-08-05 16:20:49 UTC
Thanks for the testcase
Comment 8 Matthias Clasen 2005-08-06 13:54:46 UTC
Reopening
Comment 9 Matthias Clasen 2005-08-09 05:04:32 UTC
Created attachment 50435 [details] [review]
a patch

Here is a patch which changes gvaluetransform.c to use v_long/v_ulong for
enums/flags. Still need to write tests.
Comment 10 Manish Singh 2005-08-09 05:44:23 UTC
The printf formats in the string transform functions should have the 'l' prefix.
Otherwise the patch looks good.
Comment 11 Matthias Clasen 2005-08-09 13:50:23 UTC
Created attachment 50467 [details] [review]
updated patch
Comment 12 Matthias Clasen 2005-08-09 14:13:25 UTC
2005-08-09  Matthias Clasen  <mclasen@redhat.com>

	* gvaluetransform.c: Access enum and flags
	values as v_long/v_ulong, not v_int/v_uint,
	to make value transformation of such types
	work on bigendian 64bit machines.  (#312485,
	Michael Lorenz)

Comment 13 Michael Lorenz 2005-08-09 14:46:17 UTC
tested it with 2.6.6 - applied cleanly, works fine. Thanks a lot!