From 8adb1700131e6d9b0c6ac1b5c34f2e2f58b23a9d Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 1 Nov 2018 14:24:31 +0100 Subject: [PATCH] Add swap-byte-order.sh to test libexif's byte order conversion function. This is accomplished by adding a feature to test-parse.c to switch the byte order before dumping the EXIF output. Additionally, the MakerNote values are now logged in the dump as well, in the same way as the regular tags, to better catch regressions. This new test uncovered a bug in the decoding of the MNOTE_NIKON_TAG_FIRMWARE tag whose data should not be treated as being endian-specific. --- libexif/olympus/mnote-olympus-entry.c | 2 +- test/Makefile.am | 4 +- test/swap-byte-order.sh | 17 +++ test/test-parse.c | 37 ++++- test/testdata/canon_makernote_variant_1.jpg.parsed | 97 +++++++++++++ test/testdata/fuji_makernote_variant_1.jpg.parsed | 30 ++++ .../olympus_makernote_variant_2.jpg.parsed | 39 +++++ .../olympus_makernote_variant_3.jpg.parsed | 15 ++ .../olympus_makernote_variant_4.jpg.parsed | 8 + .../olympus_makernote_variant_5.jpg.parsed | 41 ++++++ .../testdata/pentax_makernote_variant_2.jpg.parsed | 33 +++++ .../testdata/pentax_makernote_variant_3.jpg.parsed | 41 ++++++ .../testdata/pentax_makernote_variant_4.jpg.parsed | 161 +++++++++++++++++++++ 13 files changed, 515 insertions(+), 10 deletions(-) create mode 100755 test/swap-byte-order.sh diff --git a/libexif/olympus/mnote-olympus-entry.c b/libexif/olympus/mnote-olympus-entry.c index 07d0087..3fa1cf8 100644 --- a/libexif/olympus/mnote-olympus-entry.c +++ b/libexif/olympus/mnote-olympus-entry.c @@ -300,7 +300,7 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m case MNOTE_NIKON_TAG_FIRMWARE: CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); CC (entry->components, 4, v, maxlen); - vl = exif_get_long (entry->data, entry->order); + vl = exif_get_long (entry->data, EXIF_BYTE_ORDER_INTEL); if ((vl & 0xF0F0F0F0) == 0x30303030) { memcpy (v, entry->data, MIN (maxlen, 4)); } else { diff --git a/test/Makefile.am b/test/Makefile.am index 57ec617..c2dc498 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -12,11 +12,11 @@ SUBDIRS = nls # here yet. TESTS = test-mem test-value test-integers test-parse test-tagtable test-sorted \ - test-fuzzer parse-regression.sh + test-fuzzer parse-regression.sh swap-byte-order.sh check_PROGRAMS = test-mem test-mnote test-value test-integers test-parse \ test-tagtable test-sorted test-fuzzer LDADD = $(top_builddir)/libexif/libexif.la $(LTLIBINTL) -EXTRA_DIST = parse-regression.sh +EXTRA_DIST = parse-regression.sh swap-byte-order.sh diff --git a/test/swap-byte-order.sh b/test/swap-byte-order.sh new file mode 100755 index 0000000..59a9d44 --- /dev/null +++ b/test/swap-byte-order.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Swaps the byte order of test EXIF files and ensures the data don't change. +srcdir="${srcdir:-.}" +TMPLOG="$(mktemp)" +trap 'rm -f "${TMPLOG}"' 0 +# Ensure that names are untranslated +LANG= +LANGUAGE= +LC_ALL=C +export LANG LANGUAGE LC_ALL +for fn in "${srcdir}"/testdata/*.jpg ; do + ./test-parse --swap-byte-order "${fn}" | sed -e '/^New byte order:/d' > "${TMPLOG}" + if ! diff "${fn}".parsed "${TMPLOG}"; then + echo Error parsing "$fn" + exit 1 + fi +done diff --git a/test/test-parse.c b/test/test-parse.c index 5b6bfba..c427c34 100644 --- a/test/test-parse.c +++ b/test/test-parse.c @@ -71,14 +71,15 @@ static void dump_makernote(ExifData *d) { if (!name) name = "(unknown)"; printf(" Entry %u: %u, %s\n" - " Size: %u\n", i, id, name, strlen(buf)); + " Size: %u\n" + " Value: %s\n", i, id, name, strlen(buf), buf); } } } } /** Run EXIF parsing test on the given file. */ -static void test_parse(const char *filename, void *callback_data) +static void test_parse(const char *filename, void *callback_data, int swap) { ExifData *d; @@ -91,6 +92,21 @@ static void test_parse(const char *filename, void *callback_data) printf("File %s\n", fn); d = exif_data_new_from_file(filename); + printf("Byte order: %s\n", + exif_byte_order_get_name(exif_data_get_byte_order(d))); + + if (swap) { + ExifByteOrder order = EXIF_BYTE_ORDER_INTEL; + if (exif_data_get_byte_order(d) == order) { + order = EXIF_BYTE_ORDER_MOTOROLA; + } + /* This switches the byte order of the entire EXIF data structure, + * including the MakerNote */ + exif_data_set_byte_order(d, order); + printf("New byte order: %s\n", + exif_byte_order_get_name(exif_data_get_byte_order(d))); + } + exif_data_foreach_content(d, data_foreach_func, callback_data); dump_makernote(d); @@ -100,7 +116,7 @@ static void test_parse(const char *filename, void *callback_data) /** Callback function prototype for string parsing. */ -typedef void (*test_parse_func) (const char *filename, void *callback_data); +typedef void (*test_parse_func) (const char *filename, void *callback_data, int swap); /** Split string at whitespace and call callback with each substring. */ @@ -117,7 +133,7 @@ static void split_ws_string(const char *string, test_parse_func func, void *call if (str) { memcpy(str, start, len); str[len] = '\0'; - func(str, callback_data); + func(str, callback_data, 0); free(str); start = p+1; } @@ -138,10 +154,17 @@ int main(const int argc, const char *argv[]) { int i; void *callback_data = NULL; + int swap = 0; + int first = 1; + + if (argc > 1 && !strcmp(argv[1], "--swap-byte-order")) { + swap = 1; + ++first; + } - if (argc > 1) { - for (i=1; i first) { + for (i=first; i