Source code for mythx_cli.formatter.util

"""Utility functions for handling API requests and responses."""

from typing import List, Union

import click
from mythx_models.response import DetectedIssuesResponse, Severity

SEVERITY_ORDER = (
    Severity.UNKNOWN,
    Severity.NONE,
    Severity.LOW,
    Severity.MEDIUM,
    Severity.HIGH,
)


[docs]def get_source_location_by_offset(source, offset): """Retrieve the Solidity source code location based on the source map offset. :param source: The Solidity source to analyze :param offset: The source map's offset :return: The line number """ return source.encode("utf-8")[0:offset].count("\n".encode("utf-8")) + 1
[docs]def normalize_swc_list(swc_list: Union[str, List[str], None]) -> List[str]: if not swc_list: return [] if type(swc_list) == str: swc_list = swc_list.split(",") swc_list = [str(x).strip().upper() for x in swc_list] swc_list = ["SWC-{}".format(x) if not x.startswith("SWC") else x for x in swc_list] return swc_list
[docs]def set_ci_failure(): try: ctx = click.get_current_context() if ctx.obj["ci"]: ctx.obj["retval"] = 1 except RuntimeError: # skip failure when there is no active click context # i.e. the method has been called outside the click # application. pass
[docs]def filter_report( resp: DetectedIssuesResponse, min_severity: Union[str, Severity] = None, swc_blacklist: Union[str, List[str]] = None, swc_whitelist: Union[str, List[str]] = None, ) -> DetectedIssuesResponse: """Filter issues based on an SWC blacklist and minimum severity. This will remove issues of a specific SWC ID or with a too low severity from the issue reports of the passed :code:`DetectedIssuesResponse` object. The SWC blacklist can be a list of strings in the format "SWC-000" or a comma-separated string. "SWC" is case-insensitive and normalized. The SWC whitelist works in a similar way, just including selected SWCs into the resulting response object. """ min_severity = Severity(min_severity.title()) if min_severity else Severity.UNKNOWN swc_blacklist = normalize_swc_list(swc_blacklist) swc_whitelist = normalize_swc_list(swc_whitelist) new_issues = [] for report in resp.issue_reports: for issue in report.issues: is_severe = SEVERITY_ORDER.index(issue.severity) >= SEVERITY_ORDER.index( min_severity ) not_blacklisted = issue.swc_id not in swc_blacklist is_whitelisted = issue.swc_id in swc_whitelist if swc_whitelist else True if all((is_severe, is_whitelisted, not_blacklisted)): new_issues.append(issue) set_ci_failure() report.issues = new_issues return resp