Lichen

Changeset

845:9adc6e8a6fed
2018-07-09 Paul Boddie raw files shortlog changelog graph Introduced restrictions on privileged attributes, allowing internal access only. tuple-optimisations
common.py (file) compiler/ast.py (file) inspector.py (file) tests/tuple_unpack_bad.py (file)
     1.1 --- a/common.py	Thu Jul 05 23:41:16 2018 +0200
     1.2 +++ b/common.py	Mon Jul 09 17:32:35 2018 +0200
     1.3 @@ -462,7 +462,9 @@
     1.4          for i, node in enumerate(n.nodes):
     1.5              statements.append(
     1.6                  compiler.ast.Assign([node], compiler.ast.CallFunc(
     1.7 -                    compiler.ast.Getattr(compiler.ast.Name(temp), "__get_single_item_unchecked__"),
     1.8 +                    compiler.ast.Getattr(compiler.ast.Name(temp),
     1.9 +                                         "__get_single_item_unchecked__",
    1.10 +                                         privileged=True),
    1.11                      [compiler.ast.Const(i, str(i))]))
    1.12                  )
    1.13  
    1.14 @@ -1591,6 +1593,10 @@
    1.15  
    1.16  predefined_constants = "False", "None", "NotImplemented", "True"
    1.17  
    1.18 +privileged_attributes = [
    1.19 +    "__get_single_item_unchecked__",
    1.20 +    ]
    1.21 +
    1.22  unary_operator_functions = {
    1.23  
    1.24      # Unary operations.
     2.1 --- a/compiler/ast.py	Thu Jul 05 23:41:16 2018 +0200
     2.2 +++ b/compiler/ast.py	Mon Jul 09 17:32:35 2018 +0200
     2.3 @@ -868,11 +868,15 @@
     2.4          return "%s %s" % (self.expr, " ".join(map(str, self.quals)))
     2.5  
     2.6  class Getattr(Node):
     2.7 -    def __init__(self, expr, attrname, lineno=None):
     2.8 +    def __init__(self, expr, attrname, lineno=None, privileged=False):
     2.9          self.expr = expr
    2.10          self.attrname = attrname
    2.11          self.lineno = lineno
    2.12  
    2.13 +        # Support privileged internal accesses.
    2.14 +
    2.15 +        self.privileged = privileged
    2.16 +
    2.17      def getChildren(self):
    2.18          return self.expr, self.attrname
    2.19  
     3.1 --- a/inspector.py	Thu Jul 05 23:41:16 2018 +0200
     3.2 +++ b/inspector.py	Mon Jul 09 17:32:35 2018 +0200
     3.3 @@ -21,7 +21,8 @@
     3.4  """
     3.5  
     3.6  from branching import BranchTracker
     3.7 -from common import CommonModule, get_argnames, init_item, predefined_constants
     3.8 +from common import CommonModule, get_argnames, init_item, \
     3.9 +                   predefined_constants, privileged_attributes
    3.10  from modules import BasicModule, CacheWritingModule, InspectionNaming
    3.11  from errors import InspectError
    3.12  from referencing import Reference
    3.13 @@ -358,6 +359,16 @@
    3.14  
    3.15          "Process the given attribute access node 'n'."
    3.16  
    3.17 +        path = self.get_namespace_path()
    3.18 +
    3.19 +        # Test for access to special privileged attributes.
    3.20 +
    3.21 +        if isinstance(n, compiler.ast.Getattr) and \
    3.22 +           n.attrname in privileged_attributes and not n.privileged:
    3.23 +
    3.24 +            raise InspectError("Attribute %s is accessed by an unprivileged operation." %
    3.25 +                               n.attrname, path, n)
    3.26 +
    3.27          # Obtain any completed chain and return the reference to it.
    3.28  
    3.29          name_ref = self.process_attribute_chain(n)
    3.30 @@ -372,8 +383,6 @@
    3.31          # either being name-based and thus an access rooted on a name, or being
    3.32          # based on some other node and thus an anonymous access of some kind.
    3.33  
    3.34 -        path = self.get_namespace_path()
    3.35 -
    3.36          # Start with the the full attribute chain.
    3.37  
    3.38          remaining = self.attrs
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tests/tuple_unpack_bad.py	Mon Jul 09 17:32:35 2018 +0200
     4.3 @@ -0,0 +1,9 @@
     4.4 +def good(t):
     4.5 +    a, b, c = t
     4.6 +
     4.7 +def bad(t):
     4.8 +    a = t.__get_single_item_unchecked__(0)
     4.9 +
    4.10 +t = 1, 2, 3
    4.11 +good(t)
    4.12 +bad(t)