mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-03 15:55:46 +00:00
Add reference counting on class Node so that we will be able to reuse AcceptNodes
This commit is contained in:
@@ -68,15 +68,17 @@
|
|||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
Node() :
|
Node() :
|
||||||
nullable(false), left(0), right(0) { }
|
nullable(false), left(0), right(0), refcount(1) { }
|
||||||
Node(Node *left) :
|
Node(Node *left) :
|
||||||
nullable(false), left(left), right(0) { }
|
nullable(false), left(left), right(0), refcount(1) { }
|
||||||
Node(Node *left, Node *right) :
|
Node(Node *left, Node *right) :
|
||||||
nullable(false), left(left), right(right) { }
|
nullable(false), left(left), right(right), refcount(1) { }
|
||||||
virtual ~Node()
|
virtual ~Node()
|
||||||
{
|
{
|
||||||
delete left;
|
if (left)
|
||||||
delete right;
|
left->release();
|
||||||
|
if (right)
|
||||||
|
right->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,6 +95,17 @@
|
|||||||
bool nullable;
|
bool nullable;
|
||||||
State firstpos, lastpos, followpos;
|
State firstpos, lastpos, followpos;
|
||||||
Node *left, *right;
|
Node *left, *right;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need reference counting for AcceptNodes: sharing AcceptNodes
|
||||||
|
* avoids introducing duplicate States with identical accept values.
|
||||||
|
*/
|
||||||
|
unsigned int refcount;
|
||||||
|
void dup(void) { refcount++; }
|
||||||
|
void release(void) {
|
||||||
|
if (--refcount == 0)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Match nothing (//). */
|
/* Match nothing (//). */
|
||||||
@@ -419,7 +432,7 @@
|
|||||||
* Note: destroy all nodes upon failure, but *not* the start symbol once
|
* Note: destroy all nodes upon failure, but *not* the start symbol once
|
||||||
* parsing succeeds!
|
* parsing succeeds!
|
||||||
*/
|
*/
|
||||||
%destructor { delete $$; } expr terms0 terms qterm term
|
%destructor { $$->release(); } expr terms0 terms qterm term
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@@ -1482,76 +1495,7 @@ void dump_regexp(ostream& os, Node *tree)
|
|||||||
os << endl;
|
os << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* "Librarize"
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#if 0
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "value\0regexp\0value\0regexp\0\0"
|
|
||||||
*/
|
|
||||||
extern "C" char *
|
|
||||||
regexp_flex_table(const char *name, const char *regexps,
|
|
||||||
int equivalence_classes, int reverse, size_t *size)
|
|
||||||
{
|
|
||||||
Node *root = new EpsNode();
|
|
||||||
char *buffer;
|
|
||||||
|
|
||||||
while (*regexps) {
|
|
||||||
char *endptr;
|
|
||||||
uint32_t accept;
|
|
||||||
int is_rerule;
|
|
||||||
|
|
||||||
Node *tree;
|
|
||||||
|
|
||||||
accept = strtoul(regexps, &endptr, 0);
|
|
||||||
if (*endptr != '\0' || accept == 0 || accept >= (1UL << 31)) {
|
|
||||||
delete root;
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
regexps = endptr + 1;
|
|
||||||
is_rerule = NOT_RE_RULE;
|
|
||||||
if (regexp_parse(&tree, endptr, &is_rerule)) {
|
|
||||||
delete root;
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (reverse)
|
|
||||||
flip_tree(tree);
|
|
||||||
|
|
||||||
tree = new CatNode(tree, new AcceptNode(accept, is_rerule));
|
|
||||||
root = new AltNode(root, tree);
|
|
||||||
regexps = strchr(regexps, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DFA dfa(root);
|
|
||||||
map<uchar, uchar> eq;
|
|
||||||
if (equivalence_classes) {
|
|
||||||
eq = dfa.equivalence_classes();
|
|
||||||
dfa.apply_equivalence_classes(eq);
|
|
||||||
}
|
|
||||||
TransitionTable transition_table(dfa, eq);
|
|
||||||
ostringstream stream;
|
|
||||||
transition_table.flex_table(stream, name);
|
|
||||||
delete root;
|
|
||||||
|
|
||||||
streambuf *buf = stream.rdbuf();
|
|
||||||
*size = buf->in_avail();
|
|
||||||
buffer = (char *)malloc(*size);
|
|
||||||
if (!buffer)
|
|
||||||
return NULL;
|
|
||||||
buf->sgetn(buffer, *size);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <ext/stdio_filebuf.h>
|
#include <ext/stdio_filebuf.h>
|
||||||
#include "apparmor_re.h"
|
#include "apparmor_re.h"
|
||||||
|
|
||||||
@@ -1560,9 +1504,7 @@ struct aare_ruleset {
|
|||||||
Node *root;
|
Node *root;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" aare_ruleset_t *aare_new_ruleset(int reverse)
|
||||||
|
|
||||||
aare_ruleset_t *aare_new_ruleset(int reverse)
|
|
||||||
{
|
{
|
||||||
aare_ruleset_t *container = (aare_ruleset_t *) malloc(sizeof(aare_ruleset_t));
|
aare_ruleset_t *container = (aare_ruleset_t *) malloc(sizeof(aare_ruleset_t));
|
||||||
if (!container)
|
if (!container)
|
||||||
@@ -1574,16 +1516,15 @@ aare_ruleset_t *aare_new_ruleset(int reverse)
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aare_delete_ruleset(aare_ruleset_t *rules)
|
extern "C" void aare_delete_ruleset(aare_ruleset_t *rules)
|
||||||
{
|
{
|
||||||
if (rules) {
|
if (rules) {
|
||||||
delete(rules->root);
|
rules->root->release();
|
||||||
free(rules);
|
free(rules);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int aare_add_rule(aare_ruleset_t *rules, char *rule,
|
extern "C" int aare_add_rule(aare_ruleset_t *rules, char *rule, uint32_t perms)
|
||||||
uint32_t perms)
|
|
||||||
{
|
{
|
||||||
Node *tree;
|
Node *tree;
|
||||||
int is_rerule = NOT_RE_RULE;
|
int is_rerule = NOT_RE_RULE;
|
||||||
@@ -1605,7 +1546,8 @@ int aare_add_rule(aare_ruleset_t *rules, char *rule,
|
|||||||
* returns: buffer contain dfa tables, @size set to the size of the tables
|
* returns: buffer contain dfa tables, @size set to the size of the tables
|
||||||
* else NULL on failure
|
* else NULL on failure
|
||||||
*/
|
*/
|
||||||
void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes, size_t *size)
|
extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes,
|
||||||
|
size_t *size)
|
||||||
{
|
{
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
|
|
||||||
@@ -1637,5 +1579,3 @@ void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes, size_t *size)
|
|||||||
buf->sgetn(buffer, *size);
|
buf->sgetn(buffer, *size);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* extern C */
|
|
||||||
|
Reference in New Issue
Block a user