forked from Minki/linux
apparmor: add first substr match to dfa
Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
parent
a6a52579e5
commit
cf65fabc2a
@ -129,6 +129,10 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str);
|
||||
unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
|
||||
const char c);
|
||||
unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str, const char **retpos);
|
||||
unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str, int n, const char **retpos);
|
||||
|
||||
void aa_dfa_free_kref(struct kref *kref);
|
||||
|
||||
|
@ -457,3 +457,123 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* aa_dfa_match_until - traverse @dfa until accept state or end of input
|
||||
* @dfa: the dfa to match @str against (NOT NULL)
|
||||
* @start: the state of the dfa to start matching in
|
||||
* @str: the null terminated string of bytes to match against the dfa (NOT NULL)
|
||||
* @retpos: first character in str after match OR end of string
|
||||
*
|
||||
* aa_dfa_match will match @str against the dfa and return the state it
|
||||
* finished matching in. The final state can be used to look up the accepting
|
||||
* label, or as the start state of a continuing match.
|
||||
*
|
||||
* Returns: final state reached after input is consumed
|
||||
*/
|
||||
unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str, const char **retpos)
|
||||
{
|
||||
u16 *def = DEFAULT_TABLE(dfa);
|
||||
u32 *base = BASE_TABLE(dfa);
|
||||
u16 *next = NEXT_TABLE(dfa);
|
||||
u16 *check = CHECK_TABLE(dfa);
|
||||
u32 *accept = ACCEPT_TABLE(dfa);
|
||||
unsigned int state = start, pos;
|
||||
|
||||
if (state == 0)
|
||||
return 0;
|
||||
|
||||
/* current state is <state>, matching character *str */
|
||||
if (dfa->tables[YYTD_ID_EC]) {
|
||||
/* Equivalence class table defined */
|
||||
u8 *equiv = EQUIV_TABLE(dfa);
|
||||
/* default is direct to next state */
|
||||
while (*str) {
|
||||
pos = base_idx(base[state]) + equiv[(u8) *str++];
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
if (accept[state])
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* default is direct to next state */
|
||||
while (*str) {
|
||||
pos = base_idx(base[state]) + (u8) *str++;
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
if (accept[state])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*retpos = str;
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed
|
||||
* @dfa: the dfa to match @str against (NOT NULL)
|
||||
* @start: the state of the dfa to start matching in
|
||||
* @str: the string of bytes to match against the dfa (NOT NULL)
|
||||
* @n: length of the string of bytes to match
|
||||
* @retpos: first character in str after match OR str + n
|
||||
*
|
||||
* aa_dfa_match_len will match @str against the dfa and return the state it
|
||||
* finished matching in. The final state can be used to look up the accepting
|
||||
* label, or as the start state of a continuing match.
|
||||
*
|
||||
* This function will happily match again the 0 byte and only finishes
|
||||
* when @n input is consumed.
|
||||
*
|
||||
* Returns: final state reached after input is consumed
|
||||
*/
|
||||
unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str, int n, const char **retpos)
|
||||
{
|
||||
u16 *def = DEFAULT_TABLE(dfa);
|
||||
u32 *base = BASE_TABLE(dfa);
|
||||
u16 *next = NEXT_TABLE(dfa);
|
||||
u16 *check = CHECK_TABLE(dfa);
|
||||
u32 *accept = ACCEPT_TABLE(dfa);
|
||||
unsigned int state = start, pos;
|
||||
|
||||
*retpos = NULL;
|
||||
if (state == 0)
|
||||
return 0;
|
||||
|
||||
/* current state is <state>, matching character *str */
|
||||
if (dfa->tables[YYTD_ID_EC]) {
|
||||
/* Equivalence class table defined */
|
||||
u8 *equiv = EQUIV_TABLE(dfa);
|
||||
/* default is direct to next state */
|
||||
for (; n; n--) {
|
||||
pos = base_idx(base[state]) + equiv[(u8) *str++];
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
if (accept[state])
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* default is direct to next state */
|
||||
for (; n; n--) {
|
||||
pos = base_idx(base[state]) + (u8) *str++;
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
if (accept[state])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*retpos = str;
|
||||
return state;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user