From: Nick Bowler Date: Tue, 4 Aug 2009 22:06:57 +0000 (-0400) Subject: pack: Fix signed unpacking to not modify the input. X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/commitdiff_plain/10a4aed291d31295ace619ae0bcb1af5bd195c0e pack: Fix signed unpacking to not modify the input. Also change the unpack functions to use pointer to const unsigned char so that this sort of problem doesn't happen in the future. --- diff --git a/src/pack.c b/src/pack.c index e711de1..9f4998f 100644 --- a/src/pack.c +++ b/src/pack.c @@ -56,7 +56,7 @@ DEFPACK_LE(64, unsigned long long) #endif #define DEFUNPACK_BE(bits, type) type unpack_ ## bits ## _be ( \ - unsigned char *in \ + const unsigned char *in \ ) { \ type v = 0; \ unsigned i; \ @@ -68,7 +68,7 @@ DEFPACK_LE(64, unsigned long long) } #define DEFUNPACK_LE(bits, type) type unpack_ ## bits ## _le ( \ - unsigned char *in \ + const unsigned char *in \ ) { \ type v = 0; \ unsigned i; \ @@ -97,29 +97,27 @@ DEFUNPACK_LE(64, unsigned long long) */ #define DEFUNPACK_SBE(bits, max, type) type unpack_s ## bits ## _be ( \ - unsigned char *in \ + const unsigned char *in \ ) { \ type v = 0; \ unsigned i; \ int sign = (in[0] & 0x80) ? 1 : 0; \ - in[0] &= 0x7f; \ for (i = 0; i < bits/8; i++) { \ v *= 256; \ - v += in[i]; \ + v += in[i] & (i == 0 ? 0x7f : 0xff); \ } \ return sign*(-max-1) + v; \ } #define DEFUNPACK_SLE(bits, max, type) type unpack_s ## bits ## _le ( \ - unsigned char *in \ + const unsigned char *in \ ) { \ type v = 0; \ unsigned i; \ int sign = (in[bits/8 - 1] & 0x80) ? 1 : 0; \ - in[bits/8 - 1] &= 0x7f; \ for (i = 1; i <= bits/8; i++) { \ v *= 256; \ - v += in[bits/8 - i]; \ + v += in[bits/8 - i] & (i == 1 ? 0x7f : 0xff); \ } \ return sign*(-max-1) + v; \ } diff --git a/src/pack.h b/src/pack.h index 8b4874d..e79c9ad 100644 --- a/src/pack.h +++ b/src/pack.h @@ -34,28 +34,28 @@ void pack_32_le(unsigned char *, unsigned long); void pack_64_le(unsigned char *, unsigned long long); #endif -unsigned short unpack_16_be(unsigned char *); -unsigned long unpack_32_be(unsigned char *); +unsigned short unpack_16_be(const unsigned char *); +unsigned long unpack_32_be(const unsigned char *); #ifdef ULLONG_MAX -unsigned long long unpack_64_be(unsigned char *); +unsigned long long unpack_64_be(const unsigned char *); #endif -unsigned short unpack_16_le(unsigned char *); -unsigned long unpack_32_le(unsigned char *); +unsigned short unpack_16_le(const unsigned char *); +unsigned long unpack_32_le(const unsigned char *); #ifdef ULLONG_MAX -unsigned long long unpack_64_le(unsigned char *); +unsigned long long unpack_64_le(const unsigned char *); #endif -short unpack_s16_be(unsigned char *); -long unpack_s32_be(unsigned char *); +short unpack_s16_be(const unsigned char *); +long unpack_s32_be(const unsigned char *); #ifdef LLONG_MAX -long long unpack_s64_be(unsigned char *); +long long unpack_s64_be(const unsigned char *); #endif -short unpack_s16_le(unsigned char *); -long unpack_s32_le(unsigned char *); +short unpack_s16_le(const unsigned char *); +long unpack_s32_le(const unsigned char *); #ifdef LLONG_MAX -long long unpack_s64_le(unsigned char *); +long long unpack_s64_le(const unsigned char *); #endif #endif