summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-01-18 21:18:58 +0100
committerGravatar Nikias Bassen2017-01-18 21:18:58 +0100
commit82501db7920d231d763e7a263f2678f494dc754f (patch)
tree9bfaeba745317301951ffd043a623b2d1cc50a38
parentb32194d96ee4a54f07d98042bd204e52774a6a51 (diff)
downloadlibplist-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).
-rw-r--r--src/bplist.c28
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)
127#endif 127#endif
128} 128}
129 129
130static uint32_t uint24_from_be(union plist_uint_ptr buf)
131{
132 union plist_uint_ptr tmp;
133 uint32_t ret = 0;
134
135 tmp.src = &ret;
136
137 memcpy(tmp.u8ptr + 1, buf.u8ptr, 3 * sizeof(char));
138
139 byte_convert(tmp.u8ptr, sizeof(uint32_t));
140 return ret;
141}
142
143#ifndef be16toh 130#ifndef be16toh
144#ifdef __BIG_ENDIAN__ 131#ifdef __BIG_ENDIAN__
145#define be16toh(x) (x) 132#define be16toh(x) (x)
@@ -174,15 +161,22 @@ static uint32_t uint24_from_be(union plist_uint_ptr buf)
174#endif 161#endif
175#endif 162#endif
176 163
164#ifdef __BIG_ENDIAN__
165#define beNtoh(x,n) (x >> ((8-n) << 3))
166#else
167#define beNtoh(x,n) be64toh(x << ((8-n) << 3))
168#endif
169
177#define UINT_TO_HOST(x, n) \ 170#define UINT_TO_HOST(x, n) \
178 ({ \ 171 ({ \
179 union plist_uint_ptr __up; \ 172 union plist_uint_ptr __up; \
180 __up.src = x; \ 173 __up.src = (n > 8) ? x + (n - 8) : x; \
181 (n == 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \ 174 (n >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
182 (n == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \ 175 (n == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
183 (n == 3 ? uint24_from_be( __up ) : \
184 (n == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \ 176 (n == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
185 *__up.u8ptr )))); \ 177 (n == 1 ? *__up.u8ptr : \
178 beNtoh( get_unaligned(__up.u64ptr), n) \
179 )))); \
186 }) 180 })
187 181
188#define be64dec(x) \ 182#define be64dec(x) \