From 54b0f9f7b26be94e78900cecc7a5951e2f80d151 Mon Sep 17 00:00:00 2001 From: Dan Hirsch Date: Wed, 23 May 2012 01:02:31 +0200 Subject: [PATCH] Fixed bitreader to work correctly for signed 64-bit integers --- src/bitreader.c | 9 ++++++++- src/hammer.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/bitreader.c b/src/bitreader.c index 43038df..ceb464a 100644 --- a/src/bitreader.c +++ b/src/bitreader.c @@ -31,7 +31,7 @@ long long read_bits(input_stream_t* state, int count, char signed_p) { long long out = 0; int offset = 0; int final_shift = 0; - long long msb = (!!signed_p) << (count - 1); // 0 if unsigned, else 1 << (nbits - 1) + long long msb = ((signed_p ? 1LL:0) << (count - 1)); // 0 if unsigned, else 1 << (nbits - 1) // overflow check... @@ -120,6 +120,12 @@ long long read_bits(input_stream_t* state, int count, char signed_p) { .endianness = endianness_ \ } + +static void test_bitreader_ints(void) { + input_stream_t is = MK_INPUT_STREAM("\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 8, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN); + g_check_cmplong(read_bits(&is, 64, true), ==, -0x200000000); +} + static void test_bitreader_be(void) { input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN); g_check_cmpint(read_bits(&is, 3, false), ==, 0x03); @@ -165,6 +171,7 @@ void register_bitreader_tests(void) { g_test_add_func("/core/bitreader/largebits-le", test_largebits_le); g_test_add_func("/core/bitreader/offset-largebits-be", test_offset_largebits_be); g_test_add_func("/core/bitreader/offset-largebits-le", test_offset_largebits_le); + g_test_add_func("/core/bitreader/ints", test_bitreader_ints); } #endif // #ifdef INCLUDE_TESTS diff --git a/src/hammer.c b/src/hammer.c index d09f3fc..eb418fe 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -895,7 +895,7 @@ static void test_int32(void) { static void test_int16(void) { const parser_t *int16_ = int16(); - g_check_parse_ok(int16_, "\xfe\x00", 2, "s0x200"); + g_check_parse_ok(int16_, "\xfe\x00", 2, "s-0x200"); g_check_parse_failed(int16_, "\xfe", 1); }