mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-28 12:58:07 +00:00
Fix infinite loop bug in normalization.
There are some rare occassions, when lots of alternations are used that tree simplification can result in an expression of (E | (E | E)) or (E . (E . E)) where E is the epsnode both of these expressions will lead to an inifinite loop in normalize_tree as the epsnode test if ((&epsnode == t->child[dir]) && (&epsnode != t->child[!dir]) && dynamic_cast<TwoChildNode *>(t)) { and the tree node rotation test } else if ((dynamic_cast<AltNode *>(t) && dynamic_cast<AltNode *>(t->child[dir])) || (dynamic_cast<CatNode *>(t) && dynamic_cast<CatNode *>(t->child[dir]))) { end up undoing each others work, ie. eps flip rotate (E | (E | E)) --------> ((E | E) | E) -------> (E | (E | E)) Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-By: Steve Beattie <sbeattie@ubuntu.com>
This commit is contained in:
parent
04ef92ca94
commit
3a1b7bb54c
@ -187,14 +187,22 @@ void normalize_tree(Node *t, int dir)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((&epsnode == t->child[dir]) &&
|
if (dynamic_cast<TwoChildNode *>(t) &&
|
||||||
(&epsnode != t->child[!dir]) &&
|
(&epsnode == t->child[dir]) &&
|
||||||
dynamic_cast<TwoChildNode *>(t)) {
|
(&epsnode != t->child[!dir])) {
|
||||||
// (E | a) -> (a | E)
|
// (E | a) -> (a | E)
|
||||||
// Ea -> aE
|
// Ea -> aE
|
||||||
Node *c = t->child[dir];
|
// Test for E | (E | E) and E . (E . E) which will
|
||||||
t->child[dir] = t->child[!dir];
|
// result in an infinite loop
|
||||||
t->child[!dir] = c;
|
Node *c = t->child[!dir];
|
||||||
|
if (dynamic_cast<TwoChildNode *>(c) &&
|
||||||
|
&epsnode == c->child[dir] &&
|
||||||
|
&epsnode == c->child[!dir]) {
|
||||||
|
c->release();
|
||||||
|
c = &epsnode;
|
||||||
|
}
|
||||||
|
t->child[dir] = c;
|
||||||
|
t->child[!dir] = &epsnode;
|
||||||
// Don't break here as 'a' may be a tree that
|
// Don't break here as 'a' may be a tree that
|
||||||
// can be pulled up.
|
// can be pulled up.
|
||||||
} else if ((dynamic_cast<AltNode *>(t) &&
|
} else if ((dynamic_cast<AltNode *>(t) &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user