mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-28 21:07:56 +00: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
@ -571,22 +571,6 @@ void label_nodes(Node *root);
|
|||||||
unsigned long hash_NodeSet(NodeSet *ns);
|
unsigned long hash_NodeSet(NodeSet *ns);
|
||||||
void flip_tree(Node *node);
|
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 {
|
class MatchFlag: public AcceptNode {
|
||||||
public:
|
public:
|
||||||
|
@ -45,12 +45,11 @@ ostream &operator<<(ostream &os, const State &state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
State *DFA::add_new_state(NodeMap &nodemap,
|
State *DFA::add_new_state(NodeMap &nodemap,
|
||||||
pair<unsigned long, NodeSet *> index,
|
|
||||||
NodeSet *nodes, State *other, dfa_stats_t &stats)
|
NodeSet *nodes, State *other, dfa_stats_t &stats)
|
||||||
{
|
{
|
||||||
State *state = new State(nodemap.size(), nodes, other);
|
State *state = new State(nodemap.size(), nodes, other);
|
||||||
states.push_back(state);
|
states.push_back(state);
|
||||||
nodemap.insert(make_pair(index, state));
|
nodemap.insert(make_pair(ProtoState(nodes), state));
|
||||||
stats.proto_sum += nodes->size();
|
stats.proto_sum += nodes->size();
|
||||||
if (nodes->size() > stats.proto_max)
|
if (nodes->size() > stats.proto_max)
|
||||||
stats.proto_max = nodes->size();
|
stats.proto_max = nodes->size();
|
||||||
@ -62,16 +61,15 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
|
|||||||
{
|
{
|
||||||
State *target;
|
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()) {
|
if (x == nodemap.end()) {
|
||||||
/* set of nodes isn't known so create new state, and nodes to
|
/* set of nodes isn't known so create new state, and nodes to
|
||||||
* state mapping
|
* state mapping
|
||||||
*/
|
*/
|
||||||
target = add_new_state(nodemap, index, nodes, nonmatching,
|
target = add_new_state(nodemap, nodes, nonmatching, stats);
|
||||||
stats);
|
|
||||||
work_queue.push_back(target);
|
work_queue.push_back(target);
|
||||||
} else {
|
} else {
|
||||||
/* set of nodes already has a mapping so free this one */
|
/* 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;
|
NodeMap nodemap;
|
||||||
NodeSet *emptynode = new NodeSet;
|
NodeSet *emptynode = new NodeSet;
|
||||||
nonmatching = add_new_state(nodemap,
|
nonmatching = add_new_state(nodemap, emptynode, NULL, stats);
|
||||||
make_pair(hash_NodeSet(emptynode), emptynode),
|
|
||||||
emptynode, NULL, stats);
|
|
||||||
|
|
||||||
NodeSet *first = new NodeSet(root->firstpos);
|
NodeSet *first = new NodeSet(root->firstpos);
|
||||||
start = add_new_state(nodemap, make_pair(hash_NodeSet(first), first),
|
start = add_new_state(nodemap, first, nonmatching, stats);
|
||||||
first, nonmatching, stats);
|
|
||||||
|
|
||||||
/* the work_queue contains the states that need to have their
|
/* the work_queue contains the states that need to have their
|
||||||
* transitions computed. This could be done with a recursive
|
* 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();
|
dump_node_to_dfa();
|
||||||
|
|
||||||
for (NodeMap::iterator i = nodemap.begin(); i != nodemap.end(); i++)
|
for (NodeMap::iterator i = nodemap.begin(); i != nodemap.end(); i++)
|
||||||
delete i->first.second;
|
delete i->first.nodes;
|
||||||
nodemap.clear();
|
nodemap.clear();
|
||||||
|
|
||||||
if (flags & (DFA_DUMP_STATS))
|
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);
|
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
|
* State - DFA individual state information
|
||||||
* label: a unique label to identify the state used for pretty printing
|
* label: a unique label to identify the state used for pretty printing
|
||||||
@ -86,7 +120,8 @@ public:
|
|||||||
|
|
||||||
ostream &operator<<(ostream &os, const State &state);
|
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. */
|
/* Transitions in the DFA. */
|
||||||
|
|
||||||
/* dfa_stats - structure to group various stats about dfa creation
|
/* dfa_stats - structure to group various stats about dfa creation
|
||||||
@ -102,7 +137,6 @@ typedef struct dfa_stats {
|
|||||||
class DFA {
|
class DFA {
|
||||||
void dump_node_to_dfa(void);
|
void dump_node_to_dfa(void);
|
||||||
State *add_new_state(NodeMap &nodemap,
|
State *add_new_state(NodeMap &nodemap,
|
||||||
pair<unsigned long, NodeSet *> index,
|
|
||||||
NodeSet *nodes, State *other, dfa_stats_t &stats);
|
NodeSet *nodes, State *other, dfa_stats_t &stats);
|
||||||
void update_state_transitions(NodeMap &nodemap,
|
void update_state_transitions(NodeMap &nodemap,
|
||||||
list<State *> &work_queue,
|
list<State *> &work_queue,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user