Ejemplo n.º 1
0
def to_report(report: ReportData, get_file: Callable[[int, str],
                                                     File]) -> Report:
    """ Create a Report object from the given thrift report data. """
    severity = Severity._VALUES_TO_NAMES[report.severity] \
        if report.severity else 'UNSPECIFIED'

    bug_path_events: List[BugPathEvent] = []
    bug_path_positions: List[BugPathPosition] = []
    notes: List[BugPathEvent] = []
    macro_expansions: List[MacroExpansion] = []

    details = report.details
    if details:
        for e in details.pathEvents:
            bug_path_events.append(
                BugPathEvent(
                    e.msg, get_file(e.fileId, e.filePath), e.startLine,
                    e.startCol,
                    Range(e.startLine, e.startCol, e.endLine, e.endCol)))

        for p in details.executionPath:
            bug_path_positions.append(
                BugPathPosition(
                    get_file(p.fileId, p.filePath),
                    Range(p.startLine, p.startCol, p.endLine, p.endCol)))

        for e in details.extendedData:
            if e.type == ExtendedReportDataType.NOTE:
                notes.append(
                    BugPathEvent(
                        e.message, get_file(e.fileId, e.filePath), e.startLine,
                        e.startCol,
                        Range(e.startLine, e.startCol, e.endLine, e.endCol)))

            if e.type == ExtendedReportDataType.MACRO:
                name = ''
                macro_expansions.append(
                    MacroExpansion(
                        e.message, name, get_file(e.fileId, e.filePath),
                        e.startLine, e.startCol,
                        Range(e.startLine, e.startCol, e.endLine, e.endCol)))

    return Report(get_file(report.fileId, report.checkedFile),
                  report.line,
                  report.column,
                  report.checkerMsg,
                  report.checkerId,
                  severity,
                  report.bugHash,
                  report.analyzerName,
                  bug_path_events=bug_path_events or None,
                  bug_path_positions=bug_path_positions,
                  notes=notes,
                  macro_expansions=macro_expansions)
Ejemplo n.º 2
0
    def __get_bug_path_positions(
        self,
        diag,
        files: Dict[int, File]
    ) -> List[BugPathPosition]:
        """ Get bug path positions.

        In plist file the source and target of the arrows are provided as
        starting and ending ranges of the arrow. The path A->B->C is given as
        A->B and B->C, thus range B is provided twice if multiple control event
        kinds are followed each other. So in the loop we will not store the
        start point if the previous path event was a control event.
        """
        bug_path_positions = []

        prev_control_item = None
        for item in diag.get('path', []):
            if item.get('kind') != 'control':
                continue

            try:
                edges = item['edges'][0]

                edge = None
                if prev_control_item:
                    if not is_same_control_item(item, prev_control_item):
                        edge = edges['start']
                else:
                    edge = edges['start']

                if edge:
                    bug_path_positions.append(BugPathPosition(
                        file=files[edge[1]['file']],
                        range=Range(
                            edge[0]['line'], edge[0]['col'],
                            edge[1]['line'], edge[1]['col'])))

                bug_path_positions.append(BugPathPosition(
                    file=files[edges['end'][1]['file']],
                    range=Range(
                        edges['end'][0]['line'], edges['end'][0]['col'],
                        edges['end'][1]['line'], edges['end'][1]['col'])))

                prev_control_item = item
            except IndexError:
                # Edges might be empty nothing can be stored.
                continue

        return bug_path_positions
Ejemplo n.º 3
0
    def __get_macro_expansions(
        self,
        diag,
        files: Dict[int, File]
    ) -> List[MacroExpansion]:
        """ Get macro expansion. """
        macro_expansions = []

        for macro in diag.get('macro_expansions', []):
            if not macro['expansion']:
                continue

            location, start_loc, end_loc = self.__get_bug_event_locations(
                macro)
            macro_expansions.append(MacroExpansion(
                message=macro['expansion'],
                name=macro['name'],
                file=files[location['file']],
                line=location['line'],
                column=location['col'],
                range=Range(
                    start_loc['line'], start_loc['col'],
                    end_loc['line'], end_loc['col'])))

        return macro_expansions
Ejemplo n.º 4
0
    def __get_notes(self, diag, files: Dict[int, File]) -> List[BugPathEvent]:
        """ Get notes. """
        notes = []

        for note in diag.get('notes', []):
            if not note['message']:
                continue

            location, start_loc, end_loc = self.__get_bug_event_locations(note)
            notes.append(
                BugPathEvent(message=note['message'],
                             file=files[location['file']],
                             line=location['line'],
                             column=location['col'],
                             range=Range(start_loc['line'], start_loc['col'],
                                         end_loc['line'], end_loc['col'])))

        return notes
Ejemplo n.º 5
0
    def __get_bug_path_events(self, diag,
                              files: Dict[int, File]) -> List[BugPathEvent]:
        """ Get bug path events. """
        events = []

        for item in diag.get('path', []):
            if item.get('kind') != 'event':
                continue

            location, start_loc, end_loc = self.__get_bug_event_locations(item)
            events.append(
                BugPathEvent(message=item['message'],
                             file=files[location['file']],
                             line=location['line'],
                             column=location['col'],
                             range=Range(start_loc['line'], start_loc['col'],
                                         end_loc['line'], end_loc['col'])))

        return events
Ejemplo n.º 6
0
    File(os.path.join(gen_plist_dir_path, 'test.h'))
]

# Base skeletons for reports where the checker name is already available.
div_zero_skel = Report(
    SRC_FILES[1],
    7,
    14,
    'Division by zero',
    'core.DivideZero',
    report_hash='79e31a6ba028f0b7d9779faf4a6cb9cf',
    category='Logic error',
    type='Division by zero',
    bug_path_events=[
        BugPathEvent("'base' initialized to 0", SRC_FILES[0], 20, 5,
                     Range(20, 5, 20, 12)),
        BugPathEvent("Passing the value 0 via 1st parameter 'base'",
                     SRC_FILES[0], 21, 15, Range(21, 15, 21, 18)),
        BugPathEvent("Calling 'test_func'", SRC_FILES[0], 21, 5,
                     Range(21, 5, 21, 19)),
        BugPathEvent("Entered call from 'main'", SRC_FILES[0], 6, 1,
                     Range(6, 1, 6, 1)),
        BugPathEvent("Passing the value 0 via 1st parameter 'num'",
                     SRC_FILES[0], 8, 22, Range(8, 22, 8, 25)),
        BugPathEvent("Calling 'generate_id'", SRC_FILES[0], 8, 10,
                     Range(8, 10, 8, 26)),
        BugPathEvent("Entered call from 'test_func'", SRC_FILES[1], 6, 1,
                     Range(6, 1, 6, 1)),
        BugPathEvent("Division by zero", SRC_FILES[1], 7, 14,
                     Range(7, 12, 7, 17))
    ],
Ejemplo n.º 7
0
    def _get_bug_path_event_range(self, event: BugPathEvent) -> Range:
        """ Get range for bug path event. """
        if event.range:
            return event.range

        return Range(event.line, event.column, event.line, event.column)