Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.1
1.1.2
8 changes: 8 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
libmicrohammer (1.1.2-1) unstable; urgency=medium

* Fix token length truncation bug from Issue#3
* Document change to prevent confusion over magic number
* Add test to check that truncation bug is not possible

-- Justin Jones <jhjones@riversideresearch.org> Tue, 31 Mar 2026 15:00:00 -0500

libmicrohammer (1.1.1-1) unstable; urgency=medium

* Add scons uninstall target to remove installed libhammer files
Expand Down
4 changes: 3 additions & 1 deletion src/parsers/token.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ HParser *h_token(const uint8_t *str, const size_t len) {
return h_token__m(&system_allocator, str, len);
}
HParser *h_token__m(HAllocator *mm__, const uint8_t *str, const size_t len) {
// Length has to be <= 255 (uint8) as defined by HToken struct
assert(len <= UINT8_MAX);
HToken *t = h_new(HToken, 1);
uint8_t *str_cpy = h_new(uint8_t, len);
memcpy(str_cpy, str, len);
t->str = str_cpy, t->len = len;
t->str = str_cpy, t->len = (uint8_t)len;
return h_new_parser(mm__, &token_vt, t);
}
22 changes: 22 additions & 0 deletions tests/parsers/test_token.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,29 @@ static void test_reshape_token(gconstpointer backend) {
}
}

// Test token.c: len not > UINT8_MAX assert
static void test_token_len_assert(gconstpointer backend) {
(void)backend;

if (g_test_subprocess()) {
uint8_t expected[256];
memset(expected, 0x41, sizeof(expected));

HParser *parser = h_token(expected, sizeof(expected));

// Shouldn't get here
(void)parser;
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_failed();
Comment on lines +41 to +57

Copilot AI Mar 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test currently asserts that h_token aborts via assert for len == 256. That makes the test (and the bug fix) dependent on assertions being enabled; with NDEBUG, the subprocess may exit successfully and the test will fail while the truncation bug can still occur. Prefer testing a build-flag-independent behavior (e.g., h_token returns NULL for oversized lengths, or h_token supports lengths > 255 without truncation) and assert on that outcome instead of expecting an assertion failure.

Suggested change
// Test token.c: len not > UINT8_MAX assert
static void test_token_len_assert(gconstpointer backend) {
(void)backend;
if (g_test_subprocess()) {
uint8_t expected[256];
memset(expected, 0x41, sizeof(expected));
HParser *parser = h_token(expected, sizeof(expected));
// Shouldn't get here
(void)parser;
return;
}
g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_failed();
// Test token.c: ensure len == 256 is handled without truncation
static void test_token_len_assert(gconstpointer backend) {
HParserBackend be = (HParserBackend)GPOINTER_TO_INT(backend);
uint8_t expected[256];
memset(expected, 0x41, sizeof(expected));
HParser *parser = h_token(expected, sizeof(expected));
g_check_cmp_ptr(parser, !=, NULL);
h_compile(parser, be, NULL);
HParseResult *res = h_parse(parser, expected, sizeof(expected));
g_check_cmp_ptr(res, !=, NULL);
if (res) {
g_check_cmp_ptr(res->ast, !=, NULL);
if (res->ast && res->ast->token_type == TT_BYTES) {
g_check_cmp_uint(res->ast->bytes.len, ==, sizeof(expected));
}
h_parse_result_free(res);
}

Copilot uses AI. Check for mistakes.
}

void register_token_tests(void) {
g_test_add_data_func("/core/parser/packrat/reshape_token", GINT_TO_POINTER(PB_PACKRAT),
test_reshape_token);

g_test_add_data_func("/core/parser/packrat/token_len_assert", GINT_TO_POINTER(PB_PACKRAT),
test_token_len_assert);
}
Loading