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:
parent
a1482f37d8
commit
768f11b497
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 ']'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user