diff options
author | Nikias Bassen | 2017-01-18 21:18:58 +0100 |
---|---|---|
committer | Nikias Bassen | 2017-01-18 21:18:58 +0100 |
commit | 82501db7920d231d763e7a263f2678f494dc754f (patch) | |
tree | 9bfaeba745317301951ffd043a623b2d1cc50a38 /src/bplist.c | |
parent | b32194d96ee4a54f07d98042bd204e52774a6a51 (diff) | |
download | libplist-82501db7920d231d763e7a263f2678f494dc754f.tar.gz libplist-82501db7920d231d763e7a263f2678f494dc754f.tar.bz2 |
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).
Diffstat (limited to 'src/bplist.c')
-rw-r--r-- | src/bplist.c | 28 |
1 files 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) \ |