diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc index 75699ce8a..a1fea95b0 100644 --- a/parser/libapparmor_re/hfa.cc +++ b/parser/libapparmor_re/hfa.cc @@ -334,7 +334,16 @@ State *DFA::add_new_state(optflags const &opts, NodeSet *anodes, ProtoState proto; proto.init(nnodev, anodev); - State *state = new State(opts, node_map.size(), proto, other, filedfa); + State *state; + try { + state = new State(opts, node_map.size(), proto, other, filedfa); + } catch(int error) { + /* this function is called in the DFA object creation, + * and the exception prevents the destructor from + * being called, so call the helper here */ + cleanup(); + throw error; + } pair x = node_map.insert(proto, state); if (x.second == false) { delete state; @@ -522,11 +531,7 @@ DFA::DFA(Node *root, optflags const &opts, bool buildfiledfa): root(root), filed DFA::~DFA() { - anodes_cache.clear(); - nnodes_cache.clear(); - - for (Partition::iterator i = states.begin(); i != states.end(); i++) - delete *i; + cleanup(); } State *DFA::match_len(State *state, const char *str, size_t len) diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h index 5bdd00bb5..8a9ea7e70 100644 --- a/parser/libapparmor_re/hfa.h +++ b/parser/libapparmor_re/hfa.h @@ -368,6 +368,15 @@ class DFA { NodeMap node_map; std::list work_queue; + void cleanup(void) { + anodes_cache.clear(); + nnodes_cache.clear(); + + for (Partition::iterator i = states.begin(); i != states.end(); i++) { + delete *i; + } + states.clear(); + } public: DFA(Node *root, optflags const &flags, bool filedfa); virtual ~DFA();