[apparmor] [patch] Adjust type(x) == str checks in the rule classes for py2

Tyler Hicks tyhicks at canonical.com
Thu Dec 17 15:55:22 UTC 2015


On 2015-11-29 22:19:02, Christian Boltz wrote:
> Hallo,
> 
> 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.
> 
> Finally, add test-common.py with some tests for type_is_str().
> 
> References: https://bugs.launchpad.net/apparmor/+bug/1513880
> 
> 
> I propose this patch for trunk and 2.10 (except the rule/signal.py
> change because 2.10 doesn't contain SignalRule yet)
> 

It looks like you may have missed two other 'type(.*== str' patterns:

  utils/apparmor/aare.py:70:        elif type(expression) == str:
  utils/apparmor/rule/__init__.py:351:    elif type(lst) == str:

Please determine if they need the type_is_str() treatment, adjust the
patch as needed, and then commit to both branches with:

  Acked-by: Tyler Hicks <tyhicks at canonical.com>

Thanks!

Tyler

> 
> [ 21-change-rule-classes-for-py2-str-type.diff ]
> 
> === modified file ./utils/apparmor/common.py
> --- utils/apparmor/common.py    2014-12-17 00:54:04.150444000 +0100
> +++ utils/apparmor/common.py    2015-11-29 21:14:49.301661957 +0100
> @@ -245,6 +245,15 @@
>          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
> === modified file ./utils/apparmor/rule/capability.py
> --- utils/apparmor/rule/capability.py   2015-07-17 00:19:58.515815472 +0200
> +++ utils/apparmor/rule/capability.py   2015-11-29 21:15:57.373653618 +0100
> @@ -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 @@
>              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)
> === modified file ./utils/apparmor/rule/change_profile.py
> --- utils/apparmor/rule/change_profile.py       2015-07-17 00:19:58.529814641 +0200
> +++ utils/apparmor/rule/change_profile.py       2015-11-29 21:16:36.585638082 +0100
> @@ -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 @@
>          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 @@
>          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:
> === modified file ./utils/apparmor/rule/network.py
> --- utils/apparmor/rule/network.py      2015-08-24 21:32:50.122441922 +0200
> +++ utils/apparmor/rule/network.py      2015-11-29 21:17:13.125616867 +0100
> @@ -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 @@
>          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 @@
>          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:
> === modified file ./utils/apparmor/rule/rlimit.py
> --- utils/apparmor/rule/rlimit.py       2015-07-17 00:19:58.574811968 +0200
> +++ utils/apparmor/rule/rlimit.py       2015-11-29 21:18:18.101563810 +0100
> @@ -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 @@
>          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 @@
>          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')
>  
> === modified file ./utils/apparmor/rule/signal.py
> --- utils/apparmor/rule/signal.py       2015-11-23 22:15:45.411432694 +0100
> +++ utils/apparmor/rule/signal.py       2015-11-29 21:18:38.877542865 +0100
> @@ -16,7 +16,7 @@
>  
>  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 @@
>          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)
> === modified file ./utils/test/test-common.py
> --- utils/test/test-common.py   2015-11-29 21:58:47.320305689 +0100
> +++ utils/test/test-common.py   2015-11-29 21:13:39.121644329 +0100
> @@ -0,0 +1,32 @@
> +#! /usr/bin/env python
> +# ------------------------------------------------------------------
> +#
> +#    Copyright (C) 2015 Christian Boltz <apparmor at 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)
> 
> 
> Regards,
> 
> Christian Boltz
> -- 
> [BILD] Als langjährig tätiger Strafverteidiger (und Fan von Volker
> Pispers) muß ich jedoch dringend davor warnen, stinkende tote Fische in
> dieses Freiexemplar der sogenannten "Zeitung" einzuwickeln. Weil das ein
> Strafverfahren wegen Beleidigung zulasten des Fisches nach sich ziehen
> könnte.
> [http://www.kanzlei-hoenig.de/2012/keine-stinkende-tote-fische-im-briefkasten/]
> 
> 
> -- 
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20151217/58e7e594/attachment.pgp>


More information about the AppArmor mailing list