From d452f53576137ea81e93e9b441a613a3be3b8116 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Thu, 15 Dec 2011 05:08:31 -0800 Subject: [PATCH] Begin preparing to split accept nodes and non-accept nodes. Create a new ProtoState class that will encapsulate the split, but for this patch it will just contain what was done previously with NodeSet Signed-off-by: John Johansen --- parser/libapparmor_re/expr-tree.h | 16 ------------- parser/libapparmor_re/hfa.cc | 19 ++++++---------- parser/libapparmor_re/hfa.h | 38 +++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/parser/libapparmor_re/expr-tree.h b/parser/libapparmor_re/expr-tree.h index 930fffcf0..11d7d0d37 100644 --- a/parser/libapparmor_re/expr-tree.h +++ b/parser/libapparmor_re/expr-tree.h @@ -571,22 +571,6 @@ void label_nodes(Node *root); unsigned long hash_NodeSet(NodeSet *ns); void flip_tree(Node *node); -/* Comparison operator for sets of . - * Compare set hashes, and if the sets have the same hash - * do compare pointer comparison on set of , the pointer comparison - * allows us to determine which Sets of we have seen already from - * new ones when constructing the DFA. - */ -struct deref_less_than { - bool operator()(pairconst &lhs, - pairconst &rhs)const - { - if (lhs.first == rhs.first) - return *(lhs.second) < *(rhs.second); - else - return lhs.first < rhs.first; - } -}; class MatchFlag: public AcceptNode { public: diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc index 124708998..516e35479 100644 --- a/parser/libapparmor_re/hfa.cc +++ b/parser/libapparmor_re/hfa.cc @@ -45,12 +45,11 @@ ostream &operator<<(ostream &os, const State &state) } State *DFA::add_new_state(NodeMap &nodemap, - pair index, NodeSet *nodes, State *other, dfa_stats_t &stats) { State *state = new State(nodemap.size(), nodes, other); states.push_back(state); - nodemap.insert(make_pair(index, state)); + nodemap.insert(make_pair(ProtoState(nodes), state)); stats.proto_sum += nodes->size(); if (nodes->size() > stats.proto_max) stats.proto_max = nodes->size(); @@ -62,16 +61,15 @@ State *DFA::find_target_state(NodeMap &nodemap, list &work_queue, { State *target; - pair index = make_pair(hash_NodeSet(nodes), nodes); + ProtoState index(nodes); - map, State *, deref_less_than>::iterator x = nodemap.find(index); + map::iterator x = nodemap.find(index); if (x == nodemap.end()) { /* set of nodes isn't known so create new state, and nodes to * state mapping */ - target = add_new_state(nodemap, index, nodes, nonmatching, - stats); + target = add_new_state(nodemap, nodes, nonmatching, stats); work_queue.push_back(target); } else { /* set of nodes already has a mapping so free this one */ @@ -161,13 +159,10 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root) NodeMap nodemap; NodeSet *emptynode = new NodeSet; - nonmatching = add_new_state(nodemap, - make_pair(hash_NodeSet(emptynode), emptynode), - emptynode, NULL, stats); + nonmatching = add_new_state(nodemap, emptynode, NULL, stats); NodeSet *first = new NodeSet(root->firstpos); - start = add_new_state(nodemap, make_pair(hash_NodeSet(first), first), - first, nonmatching, stats); + start = add_new_state(nodemap, first, nonmatching, stats); /* the work_queue contains the states that need to have their * transitions computed. This could be done with a recursive @@ -212,7 +207,7 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root) dump_node_to_dfa(); for (NodeMap::iterator i = nodemap.begin(); i != nodemap.end(); i++) - delete i->first.second; + delete i->first.nodes; nodemap.clear(); if (flags & (DFA_DUMP_STATS)) diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h index b42501189..82dadf309 100644 --- a/parser/libapparmor_re/hfa.h +++ b/parser/libapparmor_re/hfa.h @@ -39,6 +39,40 @@ typedef list Partition; uint32_t accept_perms(NodeSet *state, uint32_t *audit_ctl, int *error); +/* + * ProtoState - NodeSet and ancillery information used to create a state + */ +class ProtoState { +public: + unsigned long hash; + NodeSet *nodes; + + ProtoState(NodeSet *n): nodes(n) + { + hash = hash_NodeSet(n); + } +}; + +/* Comparison operator for a ProtoState + * Compare set hashes, and if the sets have the same hash + * do compare pointer comparison on set of , the pointer comparison + * allows us to determine which Sets of we have seen already from + * new ones when constructing the DFA. + */ +struct deref_less_than { + bool operator()(ProtoState const &lhs, ProtoState const &rhs)const + { + if (lhs.hash == rhs.hash) { + if (lhs.nodes->size() == rhs.nodes->size()) + return *(lhs.nodes) < *(rhs.nodes); + else + return lhs.nodes->size() < rhs.nodes->size(); + } else { + return lhs.hash < rhs.hash; + } + } +}; + /* * State - DFA individual state information * label: a unique label to identify the state used for pretty printing @@ -86,7 +120,8 @@ public: ostream &operator<<(ostream &os, const State &state); -typedef map, State *, deref_less_than> NodeMap; + +typedef map NodeMap; /* Transitions in the DFA. */ /* dfa_stats - structure to group various stats about dfa creation @@ -102,7 +137,6 @@ typedef struct dfa_stats { class DFA { void dump_node_to_dfa(void); State *add_new_state(NodeMap &nodemap, - pair index, NodeSet *nodes, State *other, dfa_stats_t &stats); void update_state_transitions(NodeMap &nodemap, list &work_queue,