File 0013-Improve-UINT_TO_HOST-macro-remove-uint24_from_be-function.patch of Package libplist.4090

From 82501db7920d231d763e7a263f2678f494dc754f Mon Sep 17 00:00:00 2001
From: Nikias Bassen <nikias@gmx.li>
Date: Wed, 18 Jan 2017 21:18:58 +0100
Subject: [PATCH] bplist: Improve UINT_TO_HOST macro, remove uint24_from_be
 function

The uint24_from_be function used memcpy and a call to byte_convert.
Instead the macro now shifts the data appropriately with a new beNtoh
macro that eventually uses be64toh.
This commit also fixes the problem where binary plist data with other
non-power-of-2 sizes (like 5,6, or 7) where not handled correctly,
and actually supports sizes larger than 8 bytes though only the last
8 bytes are actually converted (nobody will come up with such a large
plist anyway).
---
 src/bplist.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/src/bplist.c b/src/bplist.c
index 73fa4e0..881c2c8 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -127,19 +127,6 @@ static void byte_convert(uint8_t * address, size_t size)
 #endif
 }
 
-static uint32_t uint24_from_be(union plist_uint_ptr buf)
-{
-    union plist_uint_ptr tmp;
-    uint32_t ret = 0;
-
-    tmp.src = &ret;
-
-    memcpy(tmp.u8ptr + 1, buf.u8ptr, 3 * sizeof(char));
-
-    byte_convert(tmp.u8ptr, sizeof(uint32_t));
-    return ret;
-}
-
 #ifndef be16toh
 #ifdef __BIG_ENDIAN__
 #define be16toh(x) (x)
@@ -174,15 +161,22 @@ static uint32_t uint24_from_be(union plist_uint_ptr buf)
 #endif
 #endif
 
+#ifdef __BIG_ENDIAN__
+#define beNtoh(x,n) (x >> ((8-n) << 3))
+#else
+#define beNtoh(x,n) be64toh(x << ((8-n) << 3))
+#endif
+
 #define UINT_TO_HOST(x, n) \
 	({ \
 		union plist_uint_ptr __up; \
-		__up.src = x; \
-		(n == 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
+		__up.src = (n > 8) ? x + (n - 8) : x; \
+		(n >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
 		(n == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
-		(n == 3 ? uint24_from_be( __up ) : \
 		(n == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
-		*__up.u8ptr )))); \
+                (n == 1 ? *__up.u8ptr : \
+		beNtoh( get_unaligned(__up.u64ptr), n) \
+		)))); \
 	})
 
 #define be64dec(x) \
openSUSE Build Service is sponsored by