def visit_BinOp(self, node):
        """
        Checks for concat using '+' and interpolation using '%' with strings
        containing HTML.

        """
        rule = None
        if isinstance(node.op, ast.Mod):
            rule = ruleset.python_interpolate_html
        elif isinstance(node.op, ast.Add):
            rule = ruleset.python_concat_html
        if rule is not None:
            visitor = HtmlStringVisitor(self.file_contents, self.results)
            visitor.visit(node.left)
            has_illegal_html_string = len(visitor.unsafe_html_string_nodes) > 0
            # Create new visitor to clear state.
            visitor = HtmlStringVisitor(self.file_contents, self.results)
            visitor.visit(node.right)
            has_illegal_html_string = has_illegal_html_string or len(
                visitor.unsafe_html_string_nodes) > 0
            if has_illegal_html_string:
                self.results.violations.append(
                    ExpressionRuleViolation(rule,
                                            self.node_to_expression(node)))
        self.generic_visit(node)
    def visit_Attribute(self, node):
        """
        Checks for uses of deprecated `display_name_with_default_escaped`.

        Arguments:
             node: An AST node.
        """
        if node.attr == 'display_name_with_default_escaped':
            self.results.violations.append(
                ExpressionRuleViolation(ruleset.python_deprecated_display_name,
                                        self.node_to_expression(node)))
        self.generic_visit(node)
    def visit_Call(self, node):
        """
        Checks for a variety of violations:
        - Checks that format() calls with nested HTML() or Text() calls use
        HTML() or Text() on the left-hand side.
        - For each HTML() and Text() call, calls into separate visitor to check
        for inner format() calls.

        Arguments:
             node: An AST node.

        """
        if isinstance(node.func, ast.Attribute) and node.func.attr == 'format':
            visitor = FormatInterpolateVisitor(self.file_contents,
                                               self.results)
            visitor.visit(node)
            if visitor.interpolates_text_or_html:
                format_caller = node.func.value
                is_caller_html_or_text = isinstance(format_caller, ast.Call) and \
                    isinstance(format_caller.func, ast.Name) and \
                    format_caller.func.id in ['Text', 'HTML']
                # If format call has nested Text() or HTML(), then the caller,
                # or left-hand-side of the format() call, must be a call to
                # Text() or HTML().
                if is_caller_html_or_text is False:
                    self.results.violations.append(
                        ExpressionRuleViolation(
                            ruleset.python_requires_html_or_text,
                            self.node_to_expression(node.func)))
        elif isinstance(node.func,
                        ast.Name) and node.func.id in ['HTML', 'Text']:
            visitor = ContainsFormatVisitor(self.file_contents, self.results)
            visitor.visit(node)
            if visitor.contains_format_call:
                self.results.violations.append(
                    ExpressionRuleViolation(ruleset.python_close_before_format,
                                            self.node_to_expression(
                                                node.func)))

        self.generic_visit(node)
    def visit_Call(self, node):
        """
        Checks that format() calls which contain HTML() or Text() use HTML() or
        Text() as the caller. In other words, Text() or HTML() must be used
        before format() for any arguments to format() that contain HTML() or
        Text().

        Arguments:
             node: An AST node.
        """
        if isinstance(node.func, ast.Attribute) and node.func.attr == 'format':
            visitor = HtmlStringVisitor(self.file_contents, self.results, True)
            visitor.visit(node)
            for unsafe_html_string_node in visitor.unsafe_html_string_nodes:
                self.results.violations.append(
                    ExpressionRuleViolation(
                        ruleset.python_wrap_html,
                        self.node_to_expression(unsafe_html_string_node)))
            # Do not continue processing child nodes of this format() node.
        else:
            self.generic_visit(node)
Esempio n. 5
0
def _add_violations(results, rule_violation, self):
    results.violations.append(ExpressionRuleViolation(rule_violation, self))