diff --git a/ChangeLog b/ChangeLog index 031e933af3..fba6fed191 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ -2002-11-24 Manish Singh +2002-11-25 Manish Singh + + * libgimpbase/gimpwire.c: use a union instead of separate types to + read/write doubles so we don't violate C's aliasing rules. Fixes + bug #85249. + +2002-11-24 Manish Singh * tools/pdbgen/pdb/image.pdb: moved FINITE definition to $extra code. Changed to use #elif, much cleaner. diff --git a/libgimpbase/gimpwire.c b/libgimpbase/gimpwire.c index 07a5075830..fd3528f5e8 100644 --- a/libgimpbase/gimpwire.c +++ b/libgimpbase/gimpwire.c @@ -366,27 +366,27 @@ wire_read_double (GIOChannel *channel, gint count, gpointer user_data) { - gdouble *t; - guint32 tmp[2]; - gint i; + union { + gdouble d; + guint32 p[2]; + } d; + gint i; #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) - guint32 swap; + guint32 swap; #endif - t = (gdouble *) tmp; - for (i = 0; i < count; i++) { - if (! wire_read_int8 (channel, (guint8 *) tmp, 8, user_data)) + if (! wire_read_int8 (channel, (guint8 *) &d.d, 8, user_data)) return FALSE; #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) - swap = g_ntohl (tmp[1]); - tmp[1] = g_ntohl (tmp[0]); - tmp[0] = swap; + swap = g_ntohl (d.p[1]); + d.p[1] = g_ntohl (d.p[0]); + d.p[0] = swap; #endif - data[i] = *t; + data[i] = d.d; } return TRUE; @@ -483,26 +483,26 @@ wire_write_double (GIOChannel *channel, gint count, gpointer user_data) { - gdouble *t; - guint32 tmp[2]; + union { + gdouble d; + guint32 p[2]; + } d; gint i; #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) guint32 swap; #endif - t = (gdouble *) tmp; - for (i = 0; i < count; i++) { - *t = data[i]; + d.d = data[i]; #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) - swap = g_htonl (tmp[1]); - tmp[1] = g_htonl (tmp[0]); - tmp[0] = swap; + swap = g_htonl (d.p[1]); + d.p[1] = g_htonl (d.p[0]); + d.p[0] = swap; #endif - if (! wire_write_int8 (channel, (guint8 *) tmp, 8, user_data)) + if (! wire_write_int8 (channel, (guint8 *) &d.d, 8, user_data)) return FALSE; #if 0