mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
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 <john.johansen@canonical.com>
This commit is contained in:
parent
9d374d4726
commit
d452f53576
3 changed files with 43 additions and 30 deletions
|
@ -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 <NodeSet *>.
|
||||
* Compare set hashes, and if the sets have the same hash
|
||||
* do compare pointer comparison on set of <Node *>, the pointer comparison
|
||||
* allows us to determine which Sets of <Node *> we have seen already from
|
||||
* new ones when constructing the DFA.
|
||||
*/
|
||||
struct deref_less_than {
|
||||
bool operator()(pair<unsigned long, NodeSet *>const &lhs,
|
||||
pair<unsigned long, NodeSet *>const &rhs)const
|
||||
{
|
||||
if (lhs.first == rhs.first)
|
||||
return *(lhs.second) < *(rhs.second);
|
||||
else
|
||||
return lhs.first < rhs.first;
|
||||
}
|
||||
};
|
||||
|
||||
class MatchFlag: public AcceptNode {
|
||||
public:
|
||||
|
|
|
@ -45,12 +45,11 @@ ostream &operator<<(ostream &os, const State &state)
|
|||
}
|
||||
|
||||
State *DFA::add_new_state(NodeMap &nodemap,
|
||||
pair<unsigned long, NodeSet *> 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<State *> &work_queue,
|
|||
{
|
||||
State *target;
|
||||
|
||||
pair<unsigned long, NodeSet *> index = make_pair(hash_NodeSet(nodes), nodes);
|
||||
ProtoState index(nodes);
|
||||
|
||||
map<pair<unsigned long, NodeSet *>, State *, deref_less_than>::iterator x = nodemap.find(index);
|
||||
map<ProtoState, State *, deref_less_than>::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))
|
||||
|
|
|
@ -39,6 +39,40 @@ typedef list<State *> 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 <Node *>, the pointer comparison
|
||||
* allows us to determine which Sets of <Node *> 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<pair<unsigned long, NodeSet *>, State *, deref_less_than> NodeMap;
|
||||
|
||||
typedef map<ProtoState, State *, deref_less_than> 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<unsigned long, NodeSet *> index,
|
||||
NodeSet *nodes, State *other, dfa_stats_t &stats);
|
||||
void update_state_transitions(NodeMap &nodemap,
|
||||
list<State *> &work_queue,
|
||||
|
|
Loading…
Add table
Reference in a new issue