diff --git a/src/bitreader.c b/src/bitreader.c index 3627df5d6f9f228c8c9fe7b6e1b0c1c30b7e7de1..fe21e439ec778aa39b3cbeb18c0b3ba4fbe337fd 100644 --- a/src/bitreader.c +++ b/src/bitreader.c @@ -62,7 +62,7 @@ int64_t h_read_bits(HInputStream* state, int count, char signed_p) { int i; for (i = 0; count > 0; i += 8) { count -= 8; - out |= state->input[state->index++] << i; + out |= (int64_t)state->input[state->index++] << i; } } } else { @@ -99,7 +99,7 @@ int64_t h_read_bits(HInputStream* state, int count, char signed_p) { if (state->endianness & BYTE_BIG_ENDIAN) { out = out << segment_len | segment; } else { // BYTE_LITTLE_ENDIAN - out |= segment << offset; + out |= (int64_t)segment << offset; offset += segment_len; } count -= segment_len; diff --git a/src/glue.c b/src/glue.c index c2d915aeaab8e8d58646569f33edc5402af43023..cb3a7ce7de4dbc435da4ddefc4dfae956a3a063f 100644 --- a/src/glue.c +++ b/src/glue.c @@ -173,7 +173,7 @@ HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va) int j; while((j = va_arg(va, int)) >= 0) - ret = h_seq_index(p, j); + ret = h_seq_index(ret, j); return ret; } diff --git a/src/t_regression.c b/src/t_regression.c index e74f16b98a7d037b19b6ece386721830720ab2c1..d05cbde0d0419addfac081a4a9292bbc18a007c4 100644 --- a/src/t_regression.c +++ b/src/t_regression.c @@ -3,6 +3,7 @@ #include "glue.h" #include "hammer.h" #include "test_suite.h" +#include "internal.h" static void test_bug118(void) { // https://github.com/UpstandingHackers/hammer/issues/118 @@ -33,6 +34,69 @@ static void test_bug118(void) { h_parse_result_free(p); } +static void test_seq_index_path(void) { + HArena *arena = h_new_arena(&system_allocator, 0); + + HParsedToken *seq = h_make_seqn(arena, 1); + HParsedToken *seq2 = h_make_seqn(arena, 2); + HParsedToken *tok1 = h_make_uint(arena, 41); + HParsedToken *tok2 = h_make_uint(arena, 42); + + seq->seq->elements[0] = seq2; + seq->seq->used = 1; + seq2->seq->elements[0] = tok1; + seq2->seq->elements[1] = tok2; + seq2->seq->used = 2; + + g_check_cmp_int(h_seq_index_path(seq, 0, -1)->token_type, ==, TT_SEQUENCE); + g_check_cmp_int(h_seq_index_path(seq, 0, 0, -1)->token_type, ==, TT_UINT); + g_check_cmp_int64(h_seq_index_path(seq, 0, 0, -1)->uint, ==, 41); + g_check_cmp_int64(h_seq_index_path(seq, 0, 1, -1)->uint, ==, 42); +} + +#define MK_INPUT_STREAM(buf,len,endianness_) \ + { \ + .input = (uint8_t*)buf, \ + .length = len, \ + .index = 0, \ + .bit_offset = 0, \ + .endianness = endianness_ \ + } + +static void test_read_bits_48(void) { + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 32, false), ==, 0x78563412); + g_check_cmp_int64(h_read_bits(&is, 16, false), ==, 0xBC9A); + } + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 31, false), ==, 0x78563412); + g_check_cmp_int64(h_read_bits(&is, 17, false), ==, 0x17934); + } + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 33, false), ==, 0x78563412); + g_check_cmp_int64(h_read_bits(&is, 17, false), ==, 0x5E4D); + } + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 36, false), ==, 0xA78563412); + g_check_cmp_int64(h_read_bits(&is, 12, false), ==, 0xBC9); + } + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 40, false), ==, 0x9A78563412); + g_check_cmp_int64(h_read_bits(&is, 8, false), ==, 0xBC); + } + { + HInputStream is = MK_INPUT_STREAM("\x12\x34\x56\x78\x9A\xBC", 6, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN); + g_check_cmp_int64(h_read_bits(&is, 48, false), ==, 0xBC9A78563412); + } +} + void register_regression_tests(void) { g_test_add_func("/core/regression/bug118", test_bug118); + g_test_add_func("/core/regression/seq_index_path", test_seq_index_path); + g_test_add_func("/core/regression/read_bits_48", test_read_bits_48); } diff --git a/src/test_suite.h b/src/test_suite.h index 1f983c7f752aadaefefa5dd637212c963cdd41d2..9a58a20fc40fe266ae286e047dfb81bed09869c8 100644 --- a/src/test_suite.h +++ b/src/test_suite.h @@ -212,6 +212,7 @@ +#define g_check_cmp_int(n1, op, n2) g_check_inttype("%d", int, n1, op, n2) #define g_check_cmp_int32(n1, op, n2) g_check_inttype("%d", int32_t, n1, op, n2) #define g_check_cmp_int64(n1, op, n2) g_check_inttype("%" PRId64, int64_t, n1, op, n2) #define g_check_cmp_uint32(n1, op, n2) g_check_inttype("%u", uint32_t, n1, op, n2)