예제 #1
0
    def register(self):
        if self.hook_on not in self.parser.modules.keys():
            self.parser.modules[self.hook_on] = []
        
        self.parser.modules[self.hook_on].append(self)

        self.module = ModuleDB()
        self.module.name = self.name
        self.module.project = self.parser.project
        self.module.save()
예제 #2
0
    def register(self):
        if self.hook_on not in self.parser.modules.keys():
            self.parser.modules[self.hook_on] = []

        self.parser.modules[self.hook_on].append(self)

        self.module = ModuleDB()
        self.module.name = self.name
        self.module.project = self.parser.project
        self.module.save()
예제 #3
0
class FormatStringModule(Module):

    name = "Format String"

    
    def __init__(self, parser):
        Module.__init__(self, parser, self.name)
        self.hook_on = clang.cindex.CursorKind.CALL_EXPR
        
        
    def register(self):
        if self.hook_on not in self.parser.modules.keys():
            self.parser.modules[self.hook_on] = []
        
        self.parser.modules[self.hook_on].append(self)

        self.module = ModuleDB()
        self.module.name = self.name
        self.module.project = self.parser.project
        self.module.save()

        
    def run(self, node):
        if node.kind != self.hook_on:
            return
        
        caller_name = node.displayname
        
        # fmt str method 1 : lookup for known functions (printf, fprintf, sprintf, etc.)
        # obsolete : handled by -Wformat-security
        
        # fmt str method 2 : compare args in static strings at function call
        number_of_args = -1
        line = ""

        unexposed_refs = list(node.get_children())
        # unexposed_refs[0] is a ref to node, args start at offset 1

        for i in range(1, len(unexposed_refs)):
            found = False
            arg_ref_node = unexposed_refs[i]

            for subref in arg_ref_node.get_children() :

                if subref.kind == clang.cindex.CursorKind.STRING_LITERAL:
                    line = self.solve_string(subref)
                    if "%" in line :
                        number_of_args = len(unexposed_refs) - i - 1
                        found = True
                        break

            if found :
                break
            
        if len(line) == 0  : return            # no static string literal found
        if "%" not in line : return            # no format symbol found
        if line.count("%%") == 2*line.count("%")  : return            # no static string literal found

        num_singles = line.count("%") - 2*line.count("%%")

        if number_of_args < num_singles:
            msg = "%s : args number mismatch (%d declared in string, %d found in function)"
            msg%= (caller_name, num_singles, number_of_args)
            print '++++', msg
            
            m = ModuleDiagnostic()
            m.name = self.name
            m.project = self.parser.project
            m.module = self.module
            m.filepath = node.location.file.name
            m.line = node.location.line
            m.message = msg
            m.save()
            
                
    def solve_string(self, node):
        start = node.extent.start.offset
        end = node.extent.end.offset

        with open(node.location.file.name, 'r') as f:
            data = f.read()
            res = data[start:end].strip()

        print len(res), ":", res
        return res
예제 #4
0
class FormatStringModule(Module):

    name = "Format String"

    def __init__(self, parser):
        Module.__init__(self, parser, self.name)
        self.hook_on = clang.cindex.CursorKind.CALL_EXPR

    def register(self):
        if self.hook_on not in self.parser.modules.keys():
            self.parser.modules[self.hook_on] = []

        self.parser.modules[self.hook_on].append(self)

        self.module = ModuleDB()
        self.module.name = self.name
        self.module.project = self.parser.project
        self.module.save()

    def run(self, node):
        if node.kind != self.hook_on:
            return

        caller_name = node.displayname

        # fmt str method 1 : lookup for known functions (printf, fprintf, sprintf, etc.)
        # obsolete : handled by -Wformat-security

        # fmt str method 2 : compare args in static strings at function call
        number_of_args = -1
        line = ""

        unexposed_refs = list(node.get_children())
        # unexposed_refs[0] is a ref to node, args start at offset 1

        for i in range(1, len(unexposed_refs)):
            found = False
            arg_ref_node = unexposed_refs[i]

            for subref in arg_ref_node.get_children():

                if subref.kind == clang.cindex.CursorKind.STRING_LITERAL:
                    line = self.solve_string(subref)
                    if "%" in line:
                        number_of_args = len(unexposed_refs) - i - 1
                        found = True
                        break

            if found:
                break

        if len(line) == 0: return  # no static string literal found
        if "%" not in line: return  # no format symbol found
        if line.count("%%") == 2 * line.count("%"):
            return  # no static string literal found

        num_singles = line.count("%") - 2 * line.count("%%")

        if number_of_args < num_singles:
            msg = "%s : args number mismatch (%d declared in string, %d found in function)"
            msg %= (caller_name, num_singles, number_of_args)
            print '++++', msg

            m = ModuleDiagnostic()
            m.name = self.name
            m.project = self.parser.project
            m.module = self.module
            m.filepath = node.location.file.name
            m.line = node.location.line
            m.message = msg
            m.save()

    def solve_string(self, node):
        start = node.extent.start.offset
        end = node.extent.end.offset

        with open(node.location.file.name, 'r') as f:
            data = f.read()
            res = data[start:end].strip()

        print len(res), ":", res
        return res