From eb3d236ba7a1a932799ccb7cf26f43ac77c171c5 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Wed, 15 Sep 2021 10:01:36 -0500 Subject: [PATCH] Fix signed integer promotion in a less elegant, but more functional way. --- src/lib/util/dbuff.h | 6 ++---- src/lib/util/net.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/lib/util/dbuff.h b/src/lib/util/dbuff.h index d0fc622e9d..cdb8bc2f89 100644 --- a/src/lib/util/dbuff.h +++ b/src/lib/util/dbuff.h @@ -1789,18 +1789,16 @@ static inline ssize_t _fr_dbuff_out_uint64v(uint64_t *num, uint8_t **pos_p, fr_d static inline ssize_t _fr_dbuff_out_int64v(int64_t *num, uint8_t **pos_p, fr_dbuff_t *dbuff, size_t length) { ssize_t slen; - bool negative; + uint8_t msb = **pos_p; fr_assert(length > 0 && length <= sizeof(uint64_t)); - negative = *fr_dbuff_current(dbuff) & 0x80; - *num = 0; slen = _fr_dbuff_out_memcpy(((uint8_t *) num) + (8 - length), pos_p, dbuff, length); if (slen <= 0) return slen; + if (msb & 0x80) memset(((uint8_t *)num), 0xff, sizeof(*num) - length); *num = fr_net_to_int64((uint8_t const *)num); - if (negative) *num = -*num; return length; } diff --git a/src/lib/util/net.h b/src/lib/util/net.h index 5493846004..e548f61104 100644 --- a/src/lib/util/net.h +++ b/src/lib/util/net.h @@ -319,6 +319,23 @@ static inline uint64_t fr_net_to_uint64v(uint8_t const *data, size_t data_len) return ntohll(num); } +static inline uint64_t fr_net_to_int64v(uint8_t const *data, size_t data_len) +{ + int64_t num = 0; + + if (unlikely(data_len > sizeof(uint64_t))) return 0; + + /* + * Copy at an offset into memory + * allocated for the uin64_t + */ + memcpy(((uint8_t *)&num) + (sizeof(uint64_t) - data_len), data, data_len); /* aligned */ + + if (*data & 0x80) memset(((uint8_t *)&num) + data_len, 0xff, sizeof(num) - data_len); + + return ntohll(num); +} + /** Convert bits (as in prefix length) to bytes, rounding up. * * @param bits number of bits in the prefix -- 2.47.2