# HG changeset patch # User gqview # Date 1163536754 0 # Node ID 9fbf210edc6f40a166b783a3afeb4a3b8e9c554e # Parent 1818abf306c1af0cf9b5883e7eb279afbe25ce63 Tue Nov 14 15:36:14 2006 John Ellis * exif.[ch]: Fix memory alignment issues, bug #1593252. diff -r 1818abf306c1 -r 9fbf210edc6f ChangeLog --- a/ChangeLog Fri Nov 10 23:15:30 2006 +0000 +++ b/ChangeLog Tue Nov 14 20:39:14 2006 +0000 @@ -1,3 +1,7 @@ +Tue Nov 14 15:36:14 2006 John Ellis + + * exif.[ch]: Fix memory alignment issues, bug #1593252. + Fri Nov 10 18:11:54 2006 John Ellis * image.c: Fix up initial scroll offset into image when auto rotated diff -r 1818abf306c1 -r 9fbf210edc6f src/exif.c --- a/src/exif.c Fri Nov 10 23:15:30 2006 +0000 +++ b/src/exif.c Tue Nov 14 20:39:14 2006 +0000 @@ -584,46 +584,65 @@ *------------------------------------------------------------------- */ +/* note: the align_buf is used to avoid alignment issues (on sparc) */ + guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo) { + guint16 align_buf; + + memcpy(&align_buf, f, sizeof(guint16)); + if (bo == EXIF_BYTE_ORDER_INTEL) - return GUINT16_FROM_LE(*(guint16*)f); + return GUINT16_FROM_LE(align_buf); else - return GUINT16_FROM_BE(*(guint16*)f); + return GUINT16_FROM_BE(align_buf); } guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo) { + guint32 align_buf; + + memcpy(&align_buf, f, sizeof(guint32)); + if (bo == EXIF_BYTE_ORDER_INTEL) - return GUINT32_FROM_LE(*(guint32*)f); + return GUINT32_FROM_LE(align_buf); else - return GUINT32_FROM_BE(*(guint32*)f); + return GUINT32_FROM_BE(align_buf); } -guint16 exif_byte_put_int16(guint16 n, ExifByteOrder bo) +void exif_byte_put_int16(unsigned char *f, guint16 n, ExifByteOrder bo) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (bo == EXIF_BYTE_ORDER_MOTOROLA) -#else + guint16 align_buf; + if (bo == EXIF_BYTE_ORDER_INTEL) -#endif - return GUINT16_SWAP_LE_BE(n); + { + align_buf = GUINT16_TO_LE(n); + } else - return n; + { + align_buf = GUINT16_TO_BE(n); + } + + memcpy(f, &align_buf, sizeof(guint16)); } -guint32 exif_byte_put_int32(guint32 n, ExifByteOrder bo) +void exif_byte_put_int32(unsigned char *f, guint32 n, ExifByteOrder bo) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (bo == EXIF_BYTE_ORDER_MOTOROLA) -#else + guint32 align_buf; + if (bo == EXIF_BYTE_ORDER_INTEL) -#endif - return GUINT32_SWAP_LE_BE(n); + { + align_buf = GUINT32_TO_LE(n); + } else - return n; + { + align_buf = GUINT32_TO_BE(n); + } + + memcpy(f, &align_buf, sizeof(guint32)); } + /* *------------------------------------------------------------------- * IFD utils @@ -1224,21 +1243,21 @@ { gchar *result; - result = exif_text_list_find_value(marker->list, ((unsigned short *)data)[0]); + result = exif_text_list_find_value(marker->list, ((guint16 *)data)[0]); string = g_string_append(string, result); g_free(result); } else for (i = 0; i < ne; i++) { g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", - ((unsigned short *)data)[i]); + ((guint16 *)data)[i]); } break; case EXIF_FORMAT_LONG_UNSIGNED: for (i = 0; i < ne; i++) { g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", - ((unsigned long *)data)[i]); + (unsigned long int)((guint32 *)data)[i]); } break; case EXIF_FORMAT_RATIONAL_UNSIGNED: @@ -1255,14 +1274,14 @@ for (i = 0; i < ne; i++) { g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", - ((short *)data)[i]); + ((gint16 *)data)[i]); } break; case EXIF_FORMAT_LONG: for (i = 0; i < ne; i++) { g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", - ((long *)data)[i]); + (long int)((gint32 *)data)[i]); } break; case EXIF_FORMAT_RATIONAL: @@ -1304,20 +1323,20 @@ switch (item->format) { case EXIF_FORMAT_SHORT: - *value = (gint)(((short *)(item->data))[0]); + *value = (gint)(((gint16 *)(item->data))[0]); return TRUE; break; case EXIF_FORMAT_SHORT_UNSIGNED: - *value = (gint)(((unsigned short *)(item->data))[0]); + *value = (gint)(((guint16 *)(item->data))[0]); return TRUE; break; case EXIF_FORMAT_LONG: - *value = (gint)(((long *)(item->data))[0]); + *value = (gint)(((gint32 *)(item->data))[0]); return TRUE; break; case EXIF_FORMAT_LONG_UNSIGNED: /* FIXME: overflow possible */ - *value = (gint)(((unsigned long *)(item->data))[0]); + *value = (gint)(((guint32 *)(item->data))[0]); return TRUE; default: /* all other type return FALSE */ diff -r 1818abf306c1 -r 9fbf210edc6f src/exif.h --- a/src/exif.h Fri Nov 10 23:15:30 2006 +0000 +++ b/src/exif.h Tue Nov 14 20:39:14 2006 +0000 @@ -213,8 +213,8 @@ guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo); guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo); -guint16 exif_byte_put_int16(guint16 n, ExifByteOrder bo); -guint32 exif_byte_put_int32(guint32 n, ExifByteOrder bo); +void exif_byte_put_int16(unsigned char *f, guint16 n, ExifByteOrder bo); +void exif_byte_put_int32(unsigned char *f, guint32 n, ExifByteOrder bo); ExifItem *exif_item_new(ExifFormatType format, guint tag, guint elements, const ExifMarker *marker);