From: Albin T. <lu...@de...> - 2013-01-08 22:11:38
|
Hi, I recently uploaded Eet 1.7.4 to Debian; this was the first version to have the testsuite enabled and to my suprise, it failed on all bigendian architectures (https://buildd.debian.org/status/package.php?p=eet&suite=experimental) I tried to find the cause of the issue, and it would seem there's a code path in eet_data_image_lossless_compressed_convert that fails to appropriately convert the input data to little endian before compressing it; this data is then uncompressed in _eet_data_image_decode_inside and, on bigend machines, converted "back" to bigend which obviously yields incorrect results. I've used the following patch to solve the issue, but since I'm no eet expert I'd gladly appreciate any input :) diff --git a/src/lib/eet_image.c b/src/lib/eet_image.c index 7116a3c..5a37bf2 100644 --- a/src/lib/eet_image.c +++ b/src/lib/eet_image.c @@ -746,13 +746,26 @@ eet_data_image_lossless_compressed_convert(int *size, { unsigned char *d, *comp; - int *header, ret, ok = 1; + int *header, *bigend_data, ret, ok = 1; uLongf buflen = 0; buflen = (((w * h * 101) / 100) + 3) * 4; ret = LZ4_compressBound((w * h * 4)); if ((ret > 0) && ((uLongf)ret > buflen)) buflen = ret; - + + if (_eet_image_words_bigendian) + { + int i; + int *bigend_data = (int *) malloc(w * h * 4); + + if (!bigend_data) return NULL; + + memcpy(bigend_data, data, w * h * 4); + for (i = 0; i < w * h; i++) SWAP32(bigend_data[i]); + + data = (const char *) bigend_data; + } + comp = malloc(buflen); if (!comp) return NULL; @@ -803,6 +816,7 @@ eet_data_image_lossless_compressed_convert(int *size, unsigned int i; for (i = 0; i < 8; i++) SWAP32(header[i]); + free(bigend_data); } memcpy(d + (8 * sizeof(int)), comp, buflen); On a related matter, the testsuite also dies with SIGBUS on SPARC due to what seems to be an arbitrarily-aligned void* used as an int* in eet_cipher. The following patch fixes the issue for me: diff --git a/src/lib/eet_cipher.c b/src/lib/eet_cipher.c index 3317538..4e1433c 100644 --- a/src/lib/eet_cipher.c +++ b/src/lib/eet_cipher.c @@ -706,9 +706,13 @@ eet_identity_check(const void *data_base, return NULL; /* Get the header */ - magic = ntohl(header[0]); - sign_len = ntohl(header[1]); - cert_len = ntohl(header[2]); + memcpy(&magic, header, sizeof(int)); + memcpy(&sign_len, header+1, sizeof(int)); + memcpy(&cert_len, header+2, sizeof(int)); + + magic = ntohl(magic); + sign_len = ntohl(sign_len); + cert_len = ntohl(cert_len); /* Verify the header */ if (magic != EET_MAGIC_SIGN) Please let me know if you want me to rework the patches, submit them with ChangeLog entries for the stable releases or whatever :) Cheers, -- Albin |