diff --git a/include/fsm/walk.h b/include/fsm/walk.h index bc030a017..a20ab68ae 100644 --- a/include/fsm/walk.h +++ b/include/fsm/walk.h @@ -7,7 +7,7 @@ #ifndef FSM_WALK_H #define FSM_WALK_H -#include +#include struct fsm; struct fsm_state; @@ -141,10 +141,6 @@ fsm_generate_matches_cb fsm_generate_cb_printf_escaped; * check and return ERROR_MISUSE if it is not, otherwise this is an * unchecked error. * - * The bitmap will be cleared before populating. Afterward, - * bm_count(bitmap) will return how many required characters were - * found. - * * There is an optional step_limit -- if this is reached, then it will * return FSM_DETECT_REQUIRED_CHARACTERS_STEP_LIMIT_REACHED and a * cleared bitmap, because any partial information could still have been @@ -157,7 +153,7 @@ enum fsm_detect_required_characters_res { }; enum fsm_detect_required_characters_res fsm_detect_required_characters(const struct fsm *dfa, size_t step_limit, - struct bm *bitmap); + uint64_t bitmap[4], size_t *char_count); #endif diff --git a/src/libfsm/detect_required.c b/src/libfsm/detect_required.c index 3701c7150..1226ac5bb 100644 --- a/src/libfsm/detect_required.c +++ b/src/libfsm/detect_required.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -95,10 +96,11 @@ static void check_symbols(const struct edge_group_iter_info *info, uint16_t *lab * edges with only one label that must be followed by all matches), so it can take * prohibitively long for large/complex DFAs. */ enum fsm_detect_required_characters_res -fsm_detect_required_characters(const struct fsm *dfa, size_t step_limit, struct bm *bitmap) +fsm_detect_required_characters(const struct fsm *dfa, size_t step_limit, + uint64_t output_bitmap[4], size_t *char_count) { assert(dfa != NULL); - assert(bitmap != NULL); + assert(output_bitmap != NULL); #if EXPENSIVE_CHECKS if (!fsm_all(dfa, fsm_isdfa)) { @@ -128,7 +130,7 @@ fsm_detect_required_characters(const struct fsm *dfa, size_t step_limit, struct } #endif - bm_clear(bitmap); + for (size_t i = 0; i < 4; i++) { output_bitmap[i] = 0; } /* If the start state is also an end state, then * it matches the empty string, so we're done. */ @@ -251,7 +253,13 @@ fsm_detect_required_characters(const struct fsm *dfa, size_t step_limit, struct } res = FSM_DETECT_REQUIRED_CHARACTERS_WRITTEN; - bm_copy(bitmap, &env.overall); + for (size_t i = 0; i < 4; i++) { + const uint64_t *w = bm_nth_word(&env.overall, i); + output_bitmap[i] = *w; + } + if (char_count != NULL) { + *char_count = bm_count(&env.overall); + } cleanup: f_free(dfa->alloc, env.stack.frames); diff --git a/tests/detect_required/detect_required_step_limit.c b/tests/detect_required/detect_required_step_limit.c index 42c1c0f5e..ad341699f 100644 --- a/tests/detect_required/detect_required_step_limit.c +++ b/tests/detect_required/detect_required_step_limit.c @@ -25,7 +25,7 @@ int main() return EXIT_FAILURE; } - struct bm bitmap; + uint64_t bitmap[4] = { 0 }; /* keep decreasing the step limit until it's hit, and check that * the bitmap is cleared. */ @@ -34,14 +34,13 @@ int main() while (!hit_step_limit) { assert(step_limit > 0); - const enum fsm_detect_required_characters_res res = fsm_detect_required_characters(fsm, step_limit, &bitmap); + const enum fsm_detect_required_characters_res res = fsm_detect_required_characters(fsm, step_limit, bitmap, NULL); if (res == FSM_DETECT_REQUIRED_CHARACTERS_STEP_LIMIT_REACHED) { hit_step_limit = true; /* this should not contain any partially complete information */ for (size_t i = 0; i < 4; i++) { - const uint64_t *w = bm_nth_word(&bitmap, i); - if (*w != 0) { + if (bitmap[i] != 0) { fprintf(stderr, "-- Test failure: partial information set when step limit reached\n"); return EXIT_FAILURE; } diff --git a/tests/detect_required/testutil.c b/tests/detect_required/testutil.c index a9682ee7d..02d89b029 100644 --- a/tests/detect_required/testutil.c +++ b/tests/detect_required/testutil.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -38,8 +38,7 @@ run_test(const struct testcase *tc) return false; } - struct bm bitmap; - bm_clear(&bitmap); + uint64_t bitmap[4] = { 0 }; { const size_t statecount = fsm_countstates(fsm); @@ -53,7 +52,7 @@ run_test(const struct testcase *tc) } - const enum fsm_detect_required_characters_res res = fsm_detect_required_characters(fsm, step_limit, &bitmap); + const enum fsm_detect_required_characters_res res = fsm_detect_required_characters(fsm, step_limit, bitmap, NULL); if (res == FSM_DETECT_REQUIRED_CHARACTERS_STEP_LIMIT_REACHED) { fprintf(stderr, "-- step limit reached, halting\n"); goto cleanup; @@ -62,14 +61,12 @@ run_test(const struct testcase *tc) char buf[257] = {0}; size_t used = 0; - assert(!bm_get(&bitmap, 0)); /* does not contain 0x00 */ - - int i = 0; - for (;;) { - const size_t next = bm_next(&bitmap, i, 1); - if (next > UCHAR_MAX) { break; } - buf[used++] = (char)next; - i = next; + assert(!u64bitset_get(bitmap, 0)); /* does not contain 0x00 */ + + for (size_t i = 0; i < 256; i++) { + if (u64bitset_get(bitmap, i)) { + buf[used++] = (char)i; + } } if (0 != strcmp(required, buf)) {