2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 18:17:09 +00:00

parser: revert changes from commit rev 3248

The changes to the parser made in commit rev 3248 were accidental and
not intended to be committed.
This commit is contained in:
Steve Beattie 2015-10-14 13:49:26 -07:00
parent a1482f37d8
commit 768f11b497
4 changed files with 110 additions and 79 deletions

View File

@ -63,7 +63,7 @@ void aare_rules::add_to_rules(Node *tree, Node *perms)
static Node *cat_with_null_seperator(Node *l, Node *r) static Node *cat_with_null_seperator(Node *l, Node *r)
{ {
return new CatNode(new CatNode(l, new CharSetNode(0)), r); return new CatNode(new CatNode(l, new CharNode(0)), r);
} }
bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,

View File

@ -232,6 +232,12 @@ void AltNode::normalize(int dir)
} else if (dynamic_cast<AltNode *>(child[dir])) { } else if (dynamic_cast<AltNode *>(child[dir])) {
// (a | b) | c -> a | (b | c) // (a | b) | c -> a | (b | c)
rotate_node(this, dir); rotate_node(this, dir);
} else if (dynamic_cast<CharSetNode *>(child[dir]) &&
dynamic_cast<CharNode *>(child[!dir])) {
// [a] | b -> b | [a]
Node *c = child[dir];
child[dir] = child[!dir];
child[!dir] = c;
} else { } else {
break; break;
} }
@ -246,77 +252,76 @@ void AltNode::normalize(int dir)
//charset conversion is disabled for now, //charset conversion is disabled for now,
//it hinders tree optimization in some cases, so it need to be either //it hinders tree optimization in some cases, so it need to be either
//done post optimization, or have extra factoring rules added //done post optimization, or have extra factoring rules added
#if 0
static Node *merge_charset(Node *a, Node *b) static Node *merge_charset(Node *a, Node *b)
{ {
Chars *from = &dynamic_cast<CharSetNode *>(b)->chars; if (dynamic_cast<CharNode *>(a) && dynamic_cast<CharNode *>(b)) {
Chars *to = &dynamic_cast<CharSetNode *>(a)->chars; Chars chars;
chars.insert(dynamic_cast<CharNode *>(a)->c);
chars.insert(dynamic_cast<CharNode *>(b)->c);
CharSetNode *n = new CharSetNode(chars);
return n;
} else if (dynamic_cast<CharNode *>(a) &&
dynamic_cast<CharSetNode *>(b)) {
Chars *chars = &dynamic_cast<CharSetNode *>(b)->chars;
chars->insert(dynamic_cast<CharNode *>(a)->c);
return b;
} else if (dynamic_cast<CharSetNode *>(a) &&
dynamic_cast<CharSetNode *>(b)) {
Chars *from = &dynamic_cast<CharSetNode *>(a)->chars;
Chars *to = &dynamic_cast<CharSetNode *>(b)->chars;
for (Chars::iterator i = from->begin(); i != from->end(); i++) for (Chars::iterator i = from->begin(); i != from->end(); i++)
to->insert(*i); to->insert(*i);
b->release(); return b;
return a; }
//return ???;
} }
/* given a constructed alt vector do duplicate elimination and merging */ static Node *alt_to_charsets(Node *t, int dir)
eliminate_dups_and_merge(vector<Node *> vec) { {
std::sort(vec->begin(), vec->end(), ???); /*
Node *first = NULL;
i = vec->begin(); Node *p = t;
if (vec->begin()->is_charset()) { Node *i = t;
for (j = i+1; *j->is_charset() && j != vec->end(); for (;dynamic_cast<AltNode *>(i);) {
j++) { if (dynamic_cast<CharNode *>(i->child[dir]) ||
merge_charset(*i, *j); dynamic_cast<CharNodeSet *>(i->child[dir])) {
*j = NULL; if (!first) {
merge_count++; first = i;
p = i;
i = i->child[!dir];
} else {
first->child[dir] = merge_charset(first->child[dir],
i->child[dir]);
p->child[!dir] = i->child[!dir];
Node *tmp = i;
i = tmp->child[!dir];
tmp->child[!dir] = NULL;
tmp->release();
} }
if (j != vec->end()) } else {
i = j; p = i;
i = i->child[!dir];
} }
}
/* merged charsets, now eliminate other dups */ // last altnode of chain check other dir as well
for (j = i + 1; ??; ???) { if (first && (dynamic_cast<charNode *>(i) ||
dynamic_cast<charNodeSet *>(i))) {
} }
*/
/*
if (dynamic_cast<CharNode *>(t->child[dir]) ||
dynamic_cast<CharSetNode *>(t->child[dir]))
char_test = true;
(char_test &&
(dynamic_cast<CharNode *>(i->child[dir]) ||
dynamic_cast<CharSetNode *>(i->child[dir])))) {
*/
return t;
} }
#endif
flatten_altnode(Node *t) {
/* flatten tree */
elimintated_alt_nodes++;
eliminate_dups_and_merge();
}
flatten_catnode(Node *t) {
/* flatten tree */
eliminated_cat_nodes++;
/* only elimination to be done is accept nodes */
}
factor() {
factor everything from right, then left
factor longest/most - look at both left and right, which is most?
to determine which dir to factor first
ab | abc | abcd | abcde
a (b | bc | bcd | bcde)
a ( b (E | c | cd | cde))
a ( b (E | c (E | d | de))
a ( b (E | c (E | d (E | e))))
so once flattened, work top to bottom
may actually want to flatten charsets into single chars in altnode
to make it easier to factor them
}
static Node *basic_alt_factor(Node *t, int dir) static Node *basic_alt_factor(Node *t, int dir)
{ {
@ -330,13 +335,6 @@ static Node *basic_alt_factor(Node *t, int dir)
t->release(); t->release();
return tmp; return tmp;
} }
if (dynamic_cast<CharSetNode *>(t->child[dir]) &&
dynamic_cast<CharSetNode *>(t->child[!dir])) {
Node *res = merge_charset(t->child[dir], t->child[!dir]);
t->child[dir] = t->child[!dir] = NULL;
t->release();
return res;
}
// (ab) | (ac) -> a(b|c) // (ab) | (ac) -> a(b|c)
if (dynamic_cast<CatNode *>(t->child[dir]) && if (dynamic_cast<CatNode *>(t->child[dir]) &&
dynamic_cast<CatNode *>(t->child[!dir]) && dynamic_cast<CatNode *>(t->child[!dir]) &&
@ -536,6 +534,8 @@ static void count_tree_nodes(Node *t, struct node_counts *counts)
} else if (dynamic_cast<StarNode *>(t)) { } else if (dynamic_cast<StarNode *>(t)) {
counts->star++; counts->star++;
count_tree_nodes(t->child[0], counts); count_tree_nodes(t->child[0], counts);
} else if (dynamic_cast<CharNode *>(t)) {
counts->charnode++;
} else if (dynamic_cast<AnyCharNode *>(t)) { } else if (dynamic_cast<AnyCharNode *>(t)) {
counts->any++; counts->any++;
} else if (dynamic_cast<CharSetNode *>(t)) { } else if (dynamic_cast<CharSetNode *>(t)) {
@ -554,11 +554,11 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
bool update; bool update;
if (flags & DFA_DUMP_TREE_STATS) { if (flags & DFA_DUMP_TREE_STATS) {
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0 }; struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 };
count_tree_nodes(t, &counts); count_tree_nodes(t, &counts);
fprintf(stderr, fprintf(stderr,
"expr tree: [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n", "expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
counts.charset, counts.notcharset, counts.charnode, counts.charset, counts.notcharset,
counts.alt, counts.plus, counts.star, counts.any, counts.alt, counts.plus, counts.star, counts.any,
counts.cat); counts.cat);
} }
@ -590,11 +590,11 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
} }
} while (update); } while (update);
if (flags & DFA_DUMP_TREE_STATS) { if (flags & DFA_DUMP_TREE_STATS) {
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0 }; struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 };
count_tree_nodes(t, &counts); count_tree_nodes(t, &counts);
fprintf(stderr, fprintf(stderr,
"simplified expr tree: [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n", "simplified expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
counts.charset, counts.notcharset, counts.charnode, counts.charset, counts.notcharset,
counts.alt, counts.plus, counts.star, counts.any, counts.alt, counts.plus, counts.star, counts.any,
counts.cat); counts.cat);
} }

View File

@ -229,11 +229,41 @@ public:
int is_postprocess(void) { return false; } int is_postprocess(void) { return false; }
}; };
/* Match one specific character (/c/). */
class CharNode: public CNode {
public:
CharNode(uchar c): c(c) { }
void follow(Cases &cases)
{
NodeSet **x = &cases.cases[c];
if (!*x) {
if (cases.otherwise)
*x = new NodeSet(*cases.otherwise);
else
*x = new NodeSet;
}
(*x)->insert(followpos.begin(), followpos.end());
}
int eq(Node *other)
{
CharNode *o = dynamic_cast<CharNode *>(other);
if (o) {
return c == o->c;
}
return 0;
}
ostream &dump(ostream &os)
{
return os << c;
}
uchar c;
};
/* Match a set of characters (/[abc]/). */ /* Match a set of characters (/[abc]/). */
class CharSetNode: public CNode { class CharSetNode: public CNode {
public: public:
CharSetNode(Chars &chars): chars(chars) { } CharSetNode(Chars &chars): chars(chars) { }
CharSetNode(uchar c): chars() { chars.insert(c); }
void follow(Cases &cases) void follow(Cases &cases)
{ {
for (Chars::iterator i = chars.begin(); i != chars.end(); i++) { for (Chars::iterator i = chars.begin(); i != chars.end(); i++) {
@ -561,6 +591,7 @@ public:
}; };
struct node_counts { struct node_counts {
int charnode;
int charset; int charset;
int notcharset; int notcharset;
int alt; int alt;

View File

@ -102,7 +102,7 @@ qterm : term
; ;
term : '.' { $$ = new AnyCharNode; } term : '.' { $$ = new AnyCharNode; }
| regex_char { $$ = new CharSetNode($1); } | regex_char { $$ = new CharNode($1); }
| '[' charset ']' { $$ = new CharSetNode(*$2); | '[' charset ']' { $$ = new CharSetNode(*$2);
delete $2; } delete $2; }
| '[' '^' charset ']' | '[' '^' charset ']'