diff --git a/src/operators/pm.cc b/src/operators/pm.cc index 6a44b2860..df03a48c8 100644 --- a/src/operators/pm.cc +++ b/src/operators/pm.cc @@ -111,7 +111,7 @@ void Pm::cleanup(acmp_node_t *n) { cleanup(n->sibling); cleanup(n->child); - postOrderTraversal(n->btree); + acmp_btree_free(n->btree); if (n->text && strlen(n->text) > 0) { free(n->text); @@ -127,18 +127,6 @@ void Pm::cleanup(acmp_node_t *n) { } -void Pm::postOrderTraversal(acmp_btree_node_t *node) { - if (node == NULL) { - return; - } - - postOrderTraversal(node->right); - postOrderTraversal(node->left); - - free(node); -} - - bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &input, RuleMessage &ruleMessage) { int rc; @@ -176,7 +164,10 @@ bool Pm::init(const std::string &file, std::string *error) { }); while (m_p->is_failtree_done == 0) { - acmp_prepare(m_p); + if (acmp_prepare(m_p) != 1) { + if (error) error->assign("Failed to prepare pattern matcher."); + return false; + } } return true; diff --git a/src/operators/pm.h b/src/operators/pm.h index 19e581fa6..b5e7ea420 100644 --- a/src/operators/pm.h +++ b/src/operators/pm.h @@ -51,7 +51,6 @@ class Pm : public Operator { bool init(const std::string &file, std::string *error) override; - void postOrderTraversal(acmp_btree_node_t *node); void cleanup(acmp_node_t *n); protected: diff --git a/src/operators/pm_from_file.cc b/src/operators/pm_from_file.cc index 52651e95c..0def9df23 100644 --- a/src/operators/pm_from_file.cc +++ b/src/operators/pm_from_file.cc @@ -81,7 +81,10 @@ bool PmFromFile::init(const std::string &config, std::string *error) { } while (m_p->is_failtree_done == 0) { - acmp_prepare(m_p); + if (acmp_prepare(m_p) != 1) { + error->assign("Failed to prepare pattern matcher."); + return false; + } } return true; diff --git a/src/utils/acmp.cc b/src/utils/acmp.cc index 1ca93b984..faf716874 100644 --- a/src/utils/acmp.cc +++ b/src/utils/acmp.cc @@ -160,16 +160,30 @@ static void acmp_connect_other_matches(ACMP *parser, acmp_node_t *node) { } } +void acmp_btree_free(acmp_btree_node_t *node) { + if (node == NULL) { + return; + } + + acmp_btree_free(node->right); + acmp_btree_free(node->left); + + free(node); +} + /** * Adds leaves to binary tree, working from sorted array of keyword tree nodes */ -static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[], +static bool acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[], int pos, int lb, int rb) { int left = 0, right = 0; if ((pos - lb) > 1) { left = lb + (pos - lb) / 2; node->left = reinterpret_cast(calloc(1, sizeof(acmp_btree_node_t))); + if (!(node->left)) { + return false; + } node->left->node = NULL; node->left->right = NULL; node->left->left = NULL; @@ -184,6 +198,9 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[], if ((rb - pos) > 1) { right = pos + (rb - pos) / 2; node->right = reinterpret_cast(calloc(1, sizeof(acmp_btree_node_t))); + if (!(node->right)) { + return false; + } node->right->node = NULL; node->right->right = NULL; node->right->left = NULL; @@ -195,18 +212,20 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[], fprintf(stderr, "%lc ->right %lc\n", (wint_t)node->node->letter, (wint_t)node->right->node->letter); #endif } - if (node->right != NULL) { - acmp_add_btree_leaves(node->right, nodes, right, pos, rb); + if ((node->right != nullptr) && !acmp_add_btree_leaves(node->right, nodes, right, pos, rb)) { + return false; } - if (node->left != NULL) { - acmp_add_btree_leaves(node->left, nodes, left, lb, pos); + if ((node->left != nullptr) && !acmp_add_btree_leaves(node->left, nodes, left, lb, pos)) { + return false; } + + return true; } /** * Builds balanced binary tree from children nodes of given node. */ -static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { +static bool acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { size_t count, i, j; acmp_node_t *child = node->child; acmp_node_t **nodes; @@ -215,7 +234,7 @@ static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { /* Build an array big enough */ for (count = 0; child != NULL; child = child->sibling) count++; nodes = (acmp_node_t **)calloc(1, count * sizeof(acmp_node_t *)); - /* ENH: Check alloc succeded */ + if (!nodes) return false; /* ENH: Combine this in the loop below - we do not need two loops */ child = node->child; @@ -236,24 +255,34 @@ static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { nodes[i] = nodes[j]; nodes[j] = tmp; } - } - if (node->btree != NULL) { - free(node->btree); - node->btree = NULL; + } + if (node->btree != nullptr) { + acmp_btree_free(node->btree); + node->btree = nullptr; } node->btree = reinterpret_cast(calloc(1, sizeof(acmp_btree_node_t))); + if (!(node->btree)) { + free(nodes); + return false; + } - /* ENH: Check alloc succeded */ pos = count / 2; node->btree->node = nodes[pos]; node->btree->letter = nodes[pos]->letter; - acmp_add_btree_leaves(node->btree, nodes, pos, -1, count); - for (i = 0; i < count; i++) { - if (nodes[i]->child != NULL) acmp_build_binary_tree(parser, nodes[i]); - } - if (nodes != NULL) { + if (!acmp_add_btree_leaves(node->btree, nodes, pos, -1, count)){ free(nodes); + return false; } + for (i = 0; i < count; i++) { + if ((nodes[i]->child != nullptr) && !acmp_build_binary_tree(parser, nodes[i])) { + free(nodes); + return false; + } + } + + free(nodes); + return true; + } /** @@ -305,7 +334,9 @@ static int acmp_connect_fail_branches(ACMP *parser) { } acmp_connect_other_matches(parser, parser->root_node); - if (parser->root_node->child != NULL) acmp_build_binary_tree(parser, parser->root_node); + if ((parser->root_node->child != nullptr) && !acmp_build_binary_tree(parser, parser->root_node)) { + return 0; + } parser->is_failtree_done = 1; return 1; diff --git a/src/utils/acmp.h b/src/utils/acmp.h index a93165fe5..0cfa6b1aa 100644 --- a/src/utils/acmp.h +++ b/src/utils/acmp.h @@ -190,6 +190,12 @@ int acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, size_ */ int acmp_prepare(ACMP *parser); +/** + * Destroying the tree and freeing the memory. + */ +void acmp_btree_free(acmp_btree_node_t *node); + + } #endif /*ACMP_H_*/