From 926182d851584bc8200f66ebe0b4d88f2c49def7 Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 14 Dec 2023 19:13:22 +0000 Subject: [PATCH] Fix an issue with expr_match --- osscan.cc | 8 ++++---- tests/expr_match_test.cc | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/osscan.cc b/osscan.cc index 18967765b..3198ad6f3 100644 --- a/osscan.cc +++ b/osscan.cc @@ -308,17 +308,17 @@ bool expr_match(const char *val, size_t vlen, const char *expr, size_t explen, b } p = expr; - const char *p_end = p + explen; + const char * const p_end = p + explen; do { const char *nest = NULL; // where the [] nested expr starts const char *subval = val; // portion of val after previous nest and before the next one size_t sublen; // length of subval not subject to nested matching q = strchr_p(p, p_end, '|'); + nest = strchr_p(p, q ? q : p_end, '['); // if we're already in a nested expr, we skip this and just match as usual. - if (do_nested) { - nest = strchr_p(p, p_end, '['); + if (do_nested && nest) { // As long as we keep finding nested portions, e.g. M[>500]ST11W[1-5] while (nest) { q1 = strchr_p(nest, p_end, ']'); @@ -343,7 +343,7 @@ bool expr_match(const char *val, size_t vlen, const char *expr, size_t explen, b //fprintf(stderr, "nest: %-.*s cmp %-.*s\n", nlen, subval, q1 - nest, nest); if (nlen > 0 && expr_match(subval, nlen, nest, q1 - nest, false)) { subval += nlen; - nest = strchr_p(p, p_end, '['); + nest = strchr_p(p, q ? q : p_end, '['); } else { goto next_expr; diff --git a/tests/expr_match_test.cc b/tests/expr_match_test.cc index b92f21fd1..142037536 100644 --- a/tests/expr_match_test.cc +++ b/tests/expr_match_test.cc @@ -181,6 +181,7 @@ const struct expr_test tests[] = { {"01", "A", false}, {"001", "A", false}, {"0001", "A", false}, + {"M5B4NNSNW5|M5B4NNSNW7|M5B4NNSNWA", "M5B4NNSNW7", true}, {"", "", true} }; @@ -188,17 +189,22 @@ int main(int argc, char **argv) { size_t num_tests = sizeof(tests) / sizeof(expr_test); size_t num_fail = 0; + size_t num_run = 0; for (size_t i=0; i < num_tests; i++) { const char *val = tests[i].val; const char *expr = tests[i].expr; bool expected = tests[i].result; + int nested = strchr(expr, '[') ? 1 : 0; std::cout << i << '\r'; - if (expected != expr_match(val, 0, expr, 0, strchr(expr, '['))) { - std::cout << "FAIL test " << i << ": " << val << - (expected ? " nomatch " : " badmatch ") << expr << std::endl; - num_fail++; + for (int n = 1; n >= nested; n--) { + num_run++; + if (expected != expr_match(val, 0, expr, 0, n)) { + std::cout << "FAIL test " << i << ": " << val << + (expected ? " nomatch " : " badmatch ") << expr << std::endl; + num_fail++; + } } } - std::cout << "Ran " << num_tests << " tests. " << num_fail << " failures." << std::endl; + std::cout << "Ran " << num_run << " tests. " << num_fail << " failures." << std::endl; return num_fail; }