mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-03 07:45:50 +00:00
Move re_match_include() to regex.py and improve it
The function is basically a wrapper around a regex, so regex.py is a much better home. While on it, rename the regex to RE_INCLUDE, change it to named matches, use RE_EOL to handle comments and compile it outside the function, which should result in a (small) performance improvement. Also rewrite re_match_include(), let it check for empty include filenames ("#include <>") and let it raise AppArmorException in that case. Finally, adjust code calling it to the new location, and add some tests for re_match_include() Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
This commit is contained in:
@@ -17,9 +17,10 @@ import re
|
||||
import os
|
||||
|
||||
import apparmor.aa
|
||||
from apparmor.aa import available_buttons, combine_name, delete_duplicates, is_known_rule, match_includes, re_match_include
|
||||
from apparmor.aa import available_buttons, combine_name, delete_duplicates, is_known_rule, match_includes
|
||||
import apparmor.aamode
|
||||
from apparmor.common import AppArmorException
|
||||
from apparmor.regex import re_match_include
|
||||
import apparmor.severity
|
||||
import apparmor.cleanprofile as cleanprofile
|
||||
import apparmor.ui as aaui
|
||||
@@ -267,7 +268,7 @@ class Merge(object):
|
||||
done = True
|
||||
elif ans == 'CMD_ALLOW':
|
||||
selection = options[selected]
|
||||
inc = apparmor.aa.re_match_include(selection)
|
||||
inc = re_match_include(selection)
|
||||
self.user.filelist[self.user.filename]['include'][inc] = True
|
||||
options.pop(selected)
|
||||
aaui.UI_Info(_('Adding %s to the file.') % selection)
|
||||
@@ -302,7 +303,7 @@ class Merge(object):
|
||||
done = True
|
||||
elif ans == 'CMD_ALLOW':
|
||||
selection = options[selected]
|
||||
inc = apparmor.aa.re_match_include(selection)
|
||||
inc = re_match_include(selection)
|
||||
deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc)
|
||||
aa[profile][hat]['include'][inc] = True
|
||||
options.pop(selected)
|
||||
@@ -524,7 +525,7 @@ class Merge(object):
|
||||
elif ans == 'CMD_ALLOW':
|
||||
path = options[selected]
|
||||
done = True
|
||||
match = apparmor.aa.re_match_include(path)
|
||||
match = re_match_include(path)
|
||||
if match:
|
||||
inc = match
|
||||
deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc)
|
||||
@@ -589,7 +590,7 @@ class Merge(object):
|
||||
|
||||
elif ans == 'CMD_NEW':
|
||||
arg = options[selected]
|
||||
if not apparmor.aa.re_match_include(arg):
|
||||
if not re_match_include(arg):
|
||||
ans = aaui.UI_GetString(_('Enter new path: '), arg)
|
||||
# if ans:
|
||||
# if not matchliteral(ans, path):
|
||||
@@ -603,7 +604,7 @@ class Merge(object):
|
||||
|
||||
elif ans == 'CMD_GLOB':
|
||||
newpath = options[selected].strip()
|
||||
if not apparmor.aa.re_match_include(newpath):
|
||||
if not re_match_include(newpath):
|
||||
newpath = apparmor.aa.glob_path(newpath)
|
||||
|
||||
if newpath not in options:
|
||||
@@ -614,7 +615,7 @@ class Merge(object):
|
||||
|
||||
elif ans == 'CMD_GLOBEXT':
|
||||
newpath = options[selected].strip()
|
||||
if not apparmor.aa.re_match_include(newpath):
|
||||
if not re_match_include(newpath):
|
||||
newpath = apparmor.aa.glob_path_withext(newpath)
|
||||
|
||||
if newpath not in options:
|
||||
|
@@ -49,7 +49,7 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK,
|
||||
RE_PROFILE_HAT_DEF, RE_PROFILE_DBUS, RE_PROFILE_MOUNT,
|
||||
RE_PROFILE_SIGNAL, RE_PROFILE_PTRACE, RE_PROFILE_PIVOT_ROOT,
|
||||
RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT,
|
||||
strip_quotes, parse_profile_start_line )
|
||||
strip_quotes, parse_profile_start_line, re_match_include )
|
||||
|
||||
import apparmor.rules as aarules
|
||||
|
||||
@@ -2112,15 +2112,6 @@ def match_includes(profile, rule_type, rule_obj):
|
||||
|
||||
return newincludes
|
||||
|
||||
def re_match_include(path):
|
||||
"""Matches the path for include and returns the include path"""
|
||||
regex_include = re.compile('^\s*#?include\s*<(.*)>\s*(#.*)?$')
|
||||
match = regex_include.search(path)
|
||||
if match:
|
||||
return match.groups()[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def valid_include(profile, incname):
|
||||
if profile and profile['include'].get(incname, False):
|
||||
return False
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
import apparmor.aa as apparmor
|
||||
from apparmor.regex import re_match_include
|
||||
|
||||
class Prof(object):
|
||||
def __init__(self, filename):
|
||||
@@ -90,7 +91,7 @@ def delete_path_duplicates(profile, profile_other, allow, same_profile=True):
|
||||
if not same_profile:
|
||||
deleted.append(entry)
|
||||
continue
|
||||
if apparmor.re_match_include(rule) or apparmor.re_match_include(entry):
|
||||
if re_match_include(rule) or re_match_include(entry):
|
||||
continue
|
||||
# Check if the rule implies entry
|
||||
if apparmor.matchliteral(rule, entry):
|
||||
|
@@ -112,6 +112,21 @@ def parse_profile_start_line(line, filename):
|
||||
return result
|
||||
|
||||
|
||||
RE_INCLUDE = re.compile('^\s*#?include\s*<(?P<magicpath>.*)>' + RE_EOL)
|
||||
|
||||
def re_match_include(line):
|
||||
"""Matches the path for include and returns the include path"""
|
||||
matches = RE_INCLUDE.search(line)
|
||||
|
||||
if not matches:
|
||||
return None
|
||||
|
||||
if not matches.group('magicpath').strip():
|
||||
raise AppArmorException(_('Syntax error: #include rule with empty filename'))
|
||||
|
||||
return matches.group('magicpath')
|
||||
|
||||
|
||||
def strip_quotes(data):
|
||||
if data[0] + data[-1] == '""':
|
||||
return data[1:-1]
|
||||
|
@@ -12,9 +12,9 @@
|
||||
import apparmor.aa as aa
|
||||
import unittest
|
||||
from common_test import AATest, setup_all_loops
|
||||
from apparmor.common import AppArmorBug
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
|
||||
from apparmor.regex import strip_quotes, parse_profile_start_line, RE_PROFILE_START, RE_PROFILE_CAP
|
||||
from apparmor.regex import strip_quotes, parse_profile_start_line, re_match_include, RE_PROFILE_START, RE_PROFILE_CAP
|
||||
|
||||
|
||||
class AARegexTest(AATest):
|
||||
@@ -465,6 +465,34 @@ class TestInvalid_parse_profile_start_line(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
parse_profile_start_line(line, 'somefile')
|
||||
|
||||
class Test_re_match_include(AATest):
|
||||
tests = [
|
||||
('#include <abstractions/base>', 'abstractions/base' ),
|
||||
('#include <abstractions/base> # comment', 'abstractions/base' ),
|
||||
('#include<abstractions/base>#comment', 'abstractions/base' ),
|
||||
(' #include <abstractions/base> ', 'abstractions/base' ),
|
||||
('include <abstractions/base>', 'abstractions/base' ), # not supported by parser
|
||||
# ('include foo', 'foo' ), # XXX not supported in tools yet
|
||||
# ('include /foo/bar', '/foo/bar' ), # XXX not supported in tools yet
|
||||
# ('include "foo"', 'foo' ), # XXX not supported in tools yet
|
||||
# ('include "/foo/bar"', '/foo/bar' ), # XXX not supported in tools yet
|
||||
(' some #include <abstractions/base>', None, ),
|
||||
(' /etc/fstab r,', None, ),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(re_match_include(params), expected)
|
||||
|
||||
class TestInvalid_re_match_include(AATest):
|
||||
tests = [
|
||||
('#include <>', AppArmorException ),
|
||||
('#include < >', AppArmorException ),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
with self.assertRaises(expected):
|
||||
re_match_include(params)
|
||||
|
||||
|
||||
class TestStripQuotes(AATest):
|
||||
def test_strip_quotes_01(self):
|
||||
|
Reference in New Issue
Block a user