def visitAugAssign(self, node, walker): """Makes a note that augmented assignment is in use. Note that although augmented assignment of attributes and subscripts is disallowed, augmented assignment of names (such as 'n += 1') is allowed. This could be a problem if untrusted code got access to a mutable database object that supports augmented assignment. """ if node.node.__class__.__name__ == 'Name': node = walker.defaultVisitNode(node) newnode = ast.Assign( [ast.AssName(node.node.name, OP_ASSIGN)], ast.CallFunc(_inplacevar_name, [ ast.Const(node.op), ast.Name(node.node.name), node.expr, ]), ) newnode.lineno = node.lineno return newnode else: node.node.in_aug_assign = True return walker.defaultVisitNode(node)
def visitGetattr(self, node, walker): """Converts attribute access to a function call. 'foo.bar' becomes '_getattr(foo, "bar")'. Also prevents augmented assignment of attributes, which would be difficult to support correctly. """ self.checkAttrName(node) node = walker.defaultVisitNode(node) if getattr(node, 'in_aug_assign', False): # We're in an augmented assignment # We might support this later... self.error(node, 'Augmented assignment of ' 'attributes is not allowed.') return ast.CallFunc(_getattr_name, [node.expr, ast.Const(node.attrname)])
return node # The security checks are performed by a set of six functions that # must be provided by the restricted environment. _apply_name = ast.Name("_apply_") _getattr_name = ast.Name("_getattr_") _getitem_name = ast.Name("_getitem_") _getiter_name = ast.Name("_getiter_") _print_target_name = ast.Name("_print") _write_name = ast.Name("_write_") _inplacevar_name = ast.Name("_inplacevar_") # Constants. _None_const = ast.Const(None) _write_const = ast.Const("write") _printed_expr = stmtNode("_print()").expr _print_target_node = stmtNode("_print = _print_()") class FuncInfo: print_used = False printed_used = False class RestrictionMutator: def __init__(self): self.warnings = [] self.errors = []