mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 16:35:02 +01:00
Adjust type(x) == str checks in the rule classes for py2
python 3 uses only the 'str' type, while python 2 also uses 'unicode'. This patch adds a type_is_str() function to common.py - depending on the python version, it checks for both. This helper function is used to keep the complexity outside of the rule classes. The rule classes get adjusted to use type_is_str() instead of checking for type(x) == str, which means they support both python versions. As pointed out by Tyler, there are also some type(...) == str checks in aare.py and rule/__init__.py which should get the same change. Finally, add test-common.py with some tests for type_is_str(). References: https://bugs.launchpad.net/apparmor/+bug/1513880 Acked-by: Tyler Hicks <tyhicks@canonical.com> for trunk and 2.10 Note: 2.10 doesn't contain SignalRule, therefore it doesn't get that part of the patch.
This commit is contained in:
parent
3073160aca
commit
6f63cf3664
9 changed files with 59 additions and 18 deletions
|
@ -14,7 +14,7 @@
|
|||
|
||||
import re
|
||||
|
||||
from apparmor.common import convert_regexp, AppArmorBug, AppArmorException
|
||||
from apparmor.common import convert_regexp, type_is_str, AppArmorBug, AppArmorException
|
||||
|
||||
class AARE(object):
|
||||
'''AARE (AppArmor Regular Expression) wrapper class'''
|
||||
|
@ -54,7 +54,7 @@ class AARE(object):
|
|||
expression = expression.orig_regex
|
||||
else:
|
||||
return self.is_equal(expression) # better safe than sorry
|
||||
elif type(expression) != str:
|
||||
elif not type_is_str(expression):
|
||||
raise AppArmorBug('AARE.match() called with unknown object: %s' % str(expression))
|
||||
|
||||
if self._regex_compiled is None:
|
||||
|
@ -67,7 +67,7 @@ class AARE(object):
|
|||
|
||||
if type(expression) == AARE:
|
||||
return self.regex == expression.regex
|
||||
elif type(expression) == str:
|
||||
elif type_is_str(expression):
|
||||
return self.regex == expression
|
||||
else:
|
||||
raise AppArmorBug('AARE.is_equal() called with unknown object: %s' % str(expression))
|
||||
|
|
|
@ -245,6 +245,15 @@ def user_perm(prof_dir):
|
|||
return False
|
||||
return True
|
||||
|
||||
def type_is_str(var):
|
||||
''' returns True if the given variable is a str (or unicode string when using python 2)'''
|
||||
if type(var) == str:
|
||||
return True
|
||||
elif sys.version_info[0] < 3 and type(var) == unicode: # python 2 sometimes uses the 'unicode' type
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class DebugLogger(object):
|
||||
def __init__(self, module_name=__name__):
|
||||
self.debugging = False
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.common import AppArmorBug
|
||||
from apparmor.common import AppArmorBug, type_is_str
|
||||
|
||||
# setup module translations
|
||||
from apparmor.translations import init_translation
|
||||
|
@ -348,7 +348,7 @@ def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name
|
|||
|
||||
if lst == all_obj:
|
||||
return None, True, None
|
||||
elif type(lst) == str:
|
||||
elif type_is_str(lst):
|
||||
result_list = {lst}
|
||||
elif (type(lst) == list or type(lst) == tuple) and len(lst) > 0:
|
||||
result_list = set(lst)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.regex import RE_PROFILE_CAP
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers
|
||||
import re
|
||||
|
||||
|
@ -47,7 +47,7 @@ class CapabilityRule(BaseRule):
|
|||
self.all_caps = True
|
||||
self.capability = set()
|
||||
else:
|
||||
if type(cap_list) == str:
|
||||
if type_is_str(cap_list):
|
||||
self.capability = {cap_list}
|
||||
elif type(cap_list) == list and len(cap_list) > 0:
|
||||
self.capability = set(cap_list)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.regex import RE_PROFILE_CHANGE_PROFILE, strip_quotes
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers, quote_if_needed
|
||||
|
||||
# setup module translations
|
||||
|
@ -48,7 +48,7 @@ class ChangeProfileRule(BaseRule):
|
|||
self.all_execconds = False
|
||||
if execcond == ChangeProfileRule.ALL:
|
||||
self.all_execconds = True
|
||||
elif type(execcond) == str:
|
||||
elif type_is_str(execcond):
|
||||
if not execcond.strip():
|
||||
raise AppArmorBug('Empty exec condition in change_profile rule')
|
||||
elif execcond.startswith('/') or execcond.startswith('@'):
|
||||
|
@ -62,7 +62,7 @@ class ChangeProfileRule(BaseRule):
|
|||
self.all_targetprofiles = False
|
||||
if targetprofile == ChangeProfileRule.ALL:
|
||||
self.all_targetprofiles = True
|
||||
elif type(targetprofile) == str:
|
||||
elif type_is_str(targetprofile):
|
||||
if targetprofile.strip():
|
||||
self.targetprofile = targetprofile
|
||||
else:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import re
|
||||
|
||||
from apparmor.regex import RE_PROFILE_NETWORK
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers
|
||||
|
||||
# setup module translations
|
||||
|
@ -66,7 +66,7 @@ class NetworkRule(BaseRule):
|
|||
self.all_domains = False
|
||||
if domain == NetworkRule.ALL:
|
||||
self.all_domains = True
|
||||
elif type(domain) == str:
|
||||
elif type_is_str(domain):
|
||||
if domain in network_domain_keywords:
|
||||
self.domain = domain
|
||||
else:
|
||||
|
@ -78,7 +78,7 @@ class NetworkRule(BaseRule):
|
|||
self.all_type_or_protocols = False
|
||||
if type_or_protocol == NetworkRule.ALL:
|
||||
self.all_type_or_protocols = True
|
||||
elif type(type_or_protocol) == str:
|
||||
elif type_is_str(type_or_protocol):
|
||||
if type_or_protocol in network_protocol_keywords:
|
||||
self.type_or_protocol = type_or_protocol
|
||||
elif type_or_protocol in network_type_keywords:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import re
|
||||
|
||||
from apparmor.regex import RE_PROFILE_RLIMIT, strip_quotes
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_comment, quote_if_needed
|
||||
|
||||
# setup module translations
|
||||
|
@ -57,7 +57,7 @@ class RlimitRule(BaseRule):
|
|||
if audit or deny or allow_keyword:
|
||||
raise AppArmorBug('The audit, allow or deny keywords are not allowed in rlimit rules.')
|
||||
|
||||
if type(rlimit) == str:
|
||||
if type_is_str(rlimit):
|
||||
if rlimit in rlimit_all:
|
||||
self.rlimit = rlimit
|
||||
else:
|
||||
|
@ -70,7 +70,7 @@ class RlimitRule(BaseRule):
|
|||
self.all_values = False
|
||||
if value == RlimitRule.ALL:
|
||||
self.all_values = True
|
||||
elif type(value) == str:
|
||||
elif type_is_str(value):
|
||||
if not value.strip():
|
||||
raise AppArmorBug('Empty value in rlimit rule')
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import re
|
|||
|
||||
from apparmor.aare import AARE
|
||||
from apparmor.regex import RE_PROFILE_SIGNAL, RE_PROFILE_NAME
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, parse_modifiers, quote_if_needed
|
||||
|
||||
# setup module translations
|
||||
|
@ -96,7 +96,7 @@ class SignalRule(BaseRule):
|
|||
self.all_peers = False
|
||||
if peer == SignalRule.ALL:
|
||||
self.all_peers = True
|
||||
elif type(peer) == str:
|
||||
elif type_is_str(peer):
|
||||
if len(peer.strip()) == 0:
|
||||
raise AppArmorBug('Passed empty peer to SignalRule: %s' % str(peer))
|
||||
self.peer = AARE(peer, False, log_event=log_event)
|
||||
|
|
32
utils/test/test-common.py
Normal file
32
utils/test/test-common.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#! /usr/bin/env python
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2015 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
from apparmor.common import type_is_str
|
||||
|
||||
class TestIs_str_type(AATest):
|
||||
tests = [
|
||||
('foo', True),
|
||||
(u'foo', True),
|
||||
(42, False),
|
||||
(True, False),
|
||||
([], False),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(type_is_str(params), expected)
|
||||
|
||||
|
||||
setup_all_loops(__name__)
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
Loading…
Add table
Reference in a new issue