def report(manager, fileobj, sev_level, conf_level, lines=-1): """''Prints issues in JSON format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ machine_output = {"results": [], "errors": []} for (fname, reason) in manager.get_skipped(): machine_output["errors"].append({"filename": fname, "reason": reason}) results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(results, list) if baseline: collector = [] for r in results: d = r.as_dict() d["more_info"] = docs_utils.get_url(d["test_id"]) if len(results[r]) > 1: d["candidates"] = [c.as_dict() for c in results[r]] collector.append(d) else: collector = [r.as_dict() for r in results] for elem in collector: elem["more_info"] = docs_utils.get_url(elem["test_id"]) itemgetter = operator.itemgetter if manager.agg_type == "vuln": machine_output["results"] = sorted(collector, key=itemgetter("test_name")) else: machine_output["results"] = sorted(collector, key=itemgetter("filename")) machine_output["metrics"] = manager.metrics.data # timezone agnostic format TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ" time_string = datetime.datetime.utcnow().strftime(TS_FORMAT) machine_output["generated_at"] = time_string result = json.dumps(machine_output, sort_keys=True, indent=2, separators=(",", ": ")) with fileobj: fileobj.write(result) if fileobj.name != sys.stdout.name: LOG.info("JSON output written to file: %s", fileobj.name)
def report(manager, fileobj, sev_level, conf_level, lines=-1): '''''Prints issues in JSON format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all ''' machine_output = {'results': [], 'errors': []} for (fname, reason) in manager.get_skipped(): machine_output['errors'].append({'filename': fname, 'reason': reason}) results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(results, list) if baseline: collector = [] for r in results: d = r.as_dict() d['more_info'] = docs_utils.get_url(d['test_id']) if len(results[r]) > 1: d['candidates'] = [c.as_dict() for c in results[r]] collector.append(d) else: collector = [r.as_dict() for r in results] for elem in collector: elem['more_info'] = docs_utils.get_url(elem['test_id']) itemgetter = operator.itemgetter if manager.agg_type == 'vuln': machine_output['results'] = sorted(collector, key=itemgetter('test_name')) else: machine_output['results'] = sorted(collector, key=itemgetter('filename')) machine_output['metrics'] = manager.metrics.data # timezone agnostic format TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ" time_string = datetime.datetime.utcnow().strftime(TS_FORMAT) machine_output['generated_at'] = time_string result = json.dumps(machine_output, sort_keys=True, indent=2, separators=(',', ': ')) with fileobj: fileobj.write(result) if fileobj.name != sys.stdout.name: LOG.info("JSON output written to file: %s", fileobj.name)
def _output_issue_str(issue, indent, show_lineno=True, show_code=True, lines=-1): # returns a list of lines that should be added to the existing lines list bits = [] bits.append("%s>> Issue: [%s:%s] %s" % (indent, issue.test_id, issue.test, issue.text)) bits.append( "%s Severity: %s Confidence: %s" % (indent, issue.severity.capitalize(), issue.confidence.capitalize())) bits.append("%s Location: %s:%s" % (indent, issue.fname, issue.lineno if show_lineno else "")) bits.append("%s More Info: %s" % (indent, docs_utils.get_url(issue.test_id))) if show_code: bits.extend( [indent + l for l in issue.get_code(lines, True).split('\n')]) return '\n'.join([bit for bit in bits])
def _template(_issue, _indent_val, _code, _color): return_val = [ "{}{}>> Issue: [{}:{}] {}".format( _indent_val, _color, _issue.test_id, _issue.test, _issue.text, ), "{} Severity: {} CWE: {} Confidence: {}".format( _indent_val, _issue.severity.capitalize(), _issue.cwe, _issue.confidence.capitalize(), ), "{} Location: {}:{}:{}".format( _indent_val, _issue.fname, _issue.lineno, _issue.col_offset ), "{} More Info: {}{}".format( _indent_val, docs_utils.get_url(_issue.test_id), screen.COLOR["DEFAULT"], ), ] if _code: return_val.append(f"{_indent_val}{_code}") return "\n".join(return_val)
def report(manager, fileobj, sev_level, conf_level, lines=-1): '''Prints issues in CSV format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all ''' results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) with fileobj: fieldnames = [ 'filename', 'test_name', 'test_id', 'issue_severity', 'issue_confidence', 'issue_text', 'line_number', 'line_range', 'more_info' ] writer = csv.DictWriter(fileobj, fieldnames=fieldnames, extrasaction='ignore') writer.writeheader() for result in results: r = result.as_dict(with_code=False) r['more_info'] = docs_utils.get_url(r['test_id']) writer.writerow(r) if fileobj.name != sys.stdout.name: LOG.info("CSV output written to file: %s", fileobj.name)
def get_bandit_url(value): try: from bandit.core.docs_utils import get_url global BANDIT_URLS if value not in BANDIT_URLS: BANDIT_URLS[value] = get_url(value) return BANDIT_URLS[value] except ImportError: return ''
def report(manager, fileobj, sev_level, conf_level, lines=-1): """Prints issues in XML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ issues = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) root = ET.Element("testsuite", name="bandit", tests=str(len(issues))) for issue in issues: test = issue.test testcase = ET.SubElement(root, "testcase", classname=issue.fname, name=test) text = ("Test ID: %s Severity: %s CWE: %s Confidence: %s\n%s\n" "Location %s:%s") text = text % ( issue.test_id, issue.severity, issue.cwe, issue.confidence, issue.text, issue.fname, issue.lineno, ) ET.SubElement( testcase, "error", more_info=docs_utils.get_url(issue.test_id), type=issue.severity, message=issue.text, ).text = text tree = ET.ElementTree(root) if fileobj.name == sys.stdout.name: fileobj = sys.stdout.buffer elif fileobj.mode == "w": fileobj.close() fileobj = open(fileobj.name, "wb") with fileobj: tree.write(fileobj, encoding="utf-8", xml_declaration=True) if fileobj.name != sys.stdout.name: LOG.info("XML output written to file: %s", fileobj.name)
def create_or_find_rule(issue_dict, rules, rule_indices): rule_id = issue_dict["test_id"] if rule_id in rules: return rules[rule_id], rule_indices[rule_id] rule = om.ReportingDescriptor( id=rule_id, name=issue_dict["test_name"], help_uri=docs_utils.get_url(rule_id) ) index = len(rules) rules[rule_id] = rule rule_indices[rule_id] = index return rule, index
def _template(_issue, _indent_val, _code): return_val = ["{}>> Issue: [{}:{}] {}". format(_indent_val, _issue.test_id, _issue.test, _issue.text), "{} Severity: {} Confidence: {}". format(_indent_val, _issue.severity.capitalize(), _issue.confidence.capitalize()), "{} Location: {}:{}". format(_indent_val, _issue.fname, _issue.lineno), "{} More Info: {}".format( _indent_val, docs_utils.get_url(_issue.test_id))] if _code: return_val.append("{}{}".format(_indent_val, _code)) return '\n'.join(return_val)
def _output_issue_str( issue, indent, show_lineno=True, show_code=True, lines=-1 ): # returns a list of lines that should be added to the existing lines list bits = [] bits.append( "%s%s>> Issue: [%s:%s] %s" % ( indent, COLOR[issue.severity], issue.test_id, issue.test, issue.text, ) ) bits.append( "%s Severity: %s CWE: %s Confidence: %s" % ( indent, issue.severity.capitalize(), str(issue.cwe), issue.confidence.capitalize(), ) ) bits.append( "%s Location: %s:%s:%s" % ( indent, issue.fname, issue.lineno if show_lineno else "", issue.col_offset if show_lineno else "", ) ) bits.append( "%s More Info: %s%s" % (indent, docs_utils.get_url(issue.test_id), COLOR["DEFAULT"]) ) if show_code: bits.extend( [indent + line for line in issue.get_code(lines, True).split("\n")] ) return "\n".join([bit for bit in bits])
def report(manager, fileobj, sev_level, conf_level, lines=-1): """Prints issues in YAML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ machine_output = {"results": [], "errors": []} for (fname, reason) in manager.get_skipped(): machine_output["errors"].append({"filename": fname, "reason": reason}) results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) collector = [r.as_dict(max_lines=lines) for r in results] for elem in collector: elem["more_info"] = docs_utils.get_url(elem["test_id"]) itemgetter = operator.itemgetter if manager.agg_type == "vuln": machine_output["results"] = sorted(collector, key=itemgetter("test_name")) else: machine_output["results"] = sorted(collector, key=itemgetter("filename")) machine_output["metrics"] = manager.metrics.data for result in machine_output["results"]: if "code" in result: code = result["code"].replace("\n", "\\n") result["code"] = code # timezone agnostic format TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ" time_string = datetime.datetime.utcnow().strftime(TS_FORMAT) machine_output["generated_at"] = time_string yaml.safe_dump(machine_output, fileobj, default_flow_style=False) if fileobj.name != sys.stdout.name: LOG.info("YAML output written to file: %s", fileobj.name)
def report(manager, fileobj, sev_level, conf_level, lines=-1): '''Prints issues in YAML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all ''' machine_output = {'results': [], 'errors': []} for (fname, reason) in manager.get_skipped(): machine_output['errors'].append({'filename': fname, 'reason': reason}) results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) collector = [r.as_dict() for r in results] for elem in collector: elem['more_info'] = docs_utils.get_url(elem['test_id']) itemgetter = operator.itemgetter if manager.agg_type == 'vuln': machine_output['results'] = sorted(collector, key=itemgetter('test_name')) else: machine_output['results'] = sorted(collector, key=itemgetter('filename')) machine_output['metrics'] = manager.metrics.data for result in machine_output['results']: if 'code' in result: code = result['code'].replace('\n', '\\n') result['code'] = code # timezone agnostic format TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ" time_string = datetime.datetime.utcnow().strftime(TS_FORMAT) machine_output['generated_at'] = time_string yaml.safe_dump(machine_output, fileobj, default_flow_style=False) if fileobj.name != sys.stdout.name: LOG.info("YAML output written to file: %s", fileobj.name)
def report(manager, fileobj, sev_level, conf_level, lines=-1): """Prints issues in CSV format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ results = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) with fileobj: fieldnames = [ "filename", "test_name", "test_id", "issue_severity", "issue_confidence", "issue_cwe", "issue_text", "line_number", "col_offset", "end_col_offset", "line_range", "more_info", ] writer = csv.DictWriter(fileobj, fieldnames=fieldnames, extrasaction="ignore") writer.writeheader() for result in results: r = result.as_dict(with_code=False) r["issue_cwe"] = r["issue_cwe"]["link"] r["more_info"] = docs_utils.get_url(r["test_id"]) writer.writerow(r) if fileobj.name != sys.stdout.name: LOG.info("CSV output written to file: %s", fileobj.name)
def report(manager, filename, sev_level, conf_level, lines=-1): """Writes issues to 'filename' in HTML format :param manager: the bandit manager object :param filename: output file name :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ header_block = u""" <!DOCTYPE html> <html> <head> <title> Bandit Report </title> <style> html * { font-family: "Arial", sans-serif; } pre { font-family: "Monaco", monospace; } .bordered-box { border: 1px solid black; padding-top:.5em; padding-bottom:.5em; padding-left:1em; } .metrics-box { font-size: 1.1em; line-height: 130%; } .metrics-title { font-size: 1.5em; font-weight: 500; margin-bottom: .25em; } .issue-description { font-size: 1.3em; font-weight: 500; } .candidate-issues { margin-left: 2em; border-left: solid 1px; LightGray; padding-left: 5%; margin-top: .2em; margin-bottom: .2em; } .issue-block { border: 1px solid LightGray; padding-left: .5em; padding-top: .5em; padding-bottom: .5em; margin-bottom: .5em; } .issue-sev-high { background-color: Pink; } .issue-sev-medium { background-color: NavajoWhite; } .issue-sev-low { background-color: LightCyan; } </style> </head> """ report_block = u""" <body> {metrics} {skipped} <br> <span id='results'> {results} </span> </body> </html> """ issue_block = u""" <span id='issue-{issue_no}'> <div class='issue-block {issue_class}'> <b>{test_name}: </b> {test_text}<br> <b>Test ID:</b> {test_id}<br> <b>Severity: </b>{severity}<br /> <b>Confidence: </b>{confidence}</br /> <b>File: </b><a href='{path}' target='_blank'>{path}</a> <br /> <b>More info: </b><a href='{url}' target='_blank'>{url}</a><br /> {code} {candidates} </div> </span> """ code_block = u""" <span id='code'> <pre> {code} </pre> </span> """ candidate_block = u""" <span id='candidates'> <br> <b>Candidates: </b> {candidate_list} </span> """ candidate_issue = u""" <span id='candidate'> <div class='candidate-issues'> <pre>{code}</pre> </div> </span> """ skipped_block = u""" <br> <span id='skipped'> <div class='bordered-box'> <b>Skipped files:</b><br><br> {files_list} </div> </span> """ metrics_block = u""" <span id='metrics'> <div class='metrics-box bordered-box'> <div class='metrics-title'> Metrics:<br> </div> Total lines of code: <span id='loc'>{loc}</span><br> Total lines skipped (#nosec): <span id='nosec'>{nosec}</span> </div> </span> """ issues = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(issues, list) # build the skipped string to insert in the report skipped_str = ''.join('%s <b>reason:</b> %s<br>' % (fname, reason) for fname, reason in manager.skipped) if skipped_str: skipped_text = skipped_block.format(files_list=skipped_str) else: skipped_text = '' # build the results string to insert in the report results_str = '' for index, issue in enumerate(issues): if not baseline or len(issues[issue]) == 1: candidates = '' code = code_block.format( code=issue.get_code(lines, True).strip('\n').lstrip(' ')) else: candidates_str = '' code = '' for candidate in issues[issue]: candidate_code = (candidate.get_code( lines, True).strip('\n').lstrip(' ')) candidates_str += candidate_issue.format(code=candidate_code) candidates = candidate_block.format(candidate_list=candidates_str) url = docs_utils.get_url(issue.test_id) results_str += issue_block.format(issue_no=index, issue_class='issue-sev-{}'.format( issue.severity.lower()), test_name=issue.test, test_id=issue.test_id, test_text=issue.text, severity=issue.severity, confidence=issue.confidence, path=issue.fname, code=code, candidates=candidates, url=url) # build the metrics string to insert in the report metrics_summary = metrics_block.format( loc=manager.metrics.data['_totals']['loc'], nosec=manager.metrics.data['_totals']['nosec']) # build the report and output it report_contents = report_block.format(metrics=metrics_summary, skipped=skipped_text, results=results_str) with utils.output_file(filename, 'w') as fout: fout.write(str(header_block.encode('utf-8'))) fout.write(str(report_contents.encode('utf-8'))) if filename is not None: logger.info("HTML output written to file: %s" % filename)
def report(manager, fileobj, sev_level, conf_level, lines=-1): """Writes issues to 'fileobj' in HTML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ header_block = """ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> Bandit Report </title> <style> html * { font-family: "Arial", sans-serif; } pre { font-family: "Monaco", monospace; } .bordered-box { border: 1px solid black; padding-top:.5em; padding-bottom:.5em; padding-left:1em; } .metrics-box { font-size: 1.1em; line-height: 130%; } .metrics-title { font-size: 1.5em; font-weight: 500; margin-bottom: .25em; } .issue-description { font-size: 1.3em; font-weight: 500; } .candidate-issues { margin-left: 2em; border-left: solid 1px; LightGray; padding-left: 5%; margin-top: .2em; margin-bottom: .2em; } .issue-block { border: 1px solid LightGray; padding-left: .5em; padding-top: .5em; padding-bottom: .5em; margin-bottom: .5em; } .issue-sev-high { background-color: Pink; } .issue-sev-medium { background-color: NavajoWhite; } .issue-sev-low { background-color: LightCyan; } </style> </head> """ report_block = """ <body> {metrics} {skipped} <br> <div id="results"> {results} </div> </body> </html> """ issue_block = """ <div id="issue-{issue_no}"> <div class="issue-block {issue_class}"> <b>{test_name}: </b> {test_text}<br> <b>Test ID:</b> {test_id}<br> <b>Severity: </b>{severity}<br> <b>CWE: </b>{cwe}<br> <b>Confidence: </b>{confidence}<br> <b>File: </b><a href="{path}" target="_blank">{path}</a> <br> <b>Line number: </b>{line_number}<br> <b>More info: </b><a href="{url}" target="_blank">{url}</a><br> {code} {candidates} </div> </div> """ code_block = """ <div class="code"> <pre> {code} </pre> </div> """ candidate_block = """ <div class="candidates"> <br> <b>Candidates: </b> {candidate_list} </div> """ candidate_issue = """ <div class="candidate"> <div class="candidate-issues"> <pre>{code}</pre> </div> </div> """ skipped_block = """ <br> <div id="skipped"> <div class="bordered-box"> <b>Skipped files:</b><br><br> {files_list} </div> </div> """ metrics_block = """ <div id="metrics"> <div class="metrics-box bordered-box"> <div class="metrics-title"> Metrics:<br> </div> Total lines of code: <span id="loc">{loc}</span><br> Total lines skipped (#nosec): <span id="nosec">{nosec}</span> </div> </div> """ issues = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(issues, list) # build the skipped string to insert in the report skipped_str = "".join(f"{fname} <b>reason:</b> {reason}<br>" for fname, reason in manager.get_skipped()) if skipped_str: skipped_text = skipped_block.format(files_list=skipped_str) else: skipped_text = "" # build the results string to insert in the report results_str = "" for index, issue in enumerate(issues): if not baseline or len(issues[issue]) == 1: candidates = "" safe_code = html_escape( issue.get_code(lines, True).strip("\n").lstrip(" ")) code = code_block.format(code=safe_code) else: candidates_str = "" code = "" for candidate in issues[issue]: candidate_code = html_escape( candidate.get_code(lines, True).strip("\n").lstrip(" ")) candidates_str += candidate_issue.format(code=candidate_code) candidates = candidate_block.format(candidate_list=candidates_str) url = docs_utils.get_url(issue.test_id) results_str += issue_block.format( issue_no=index, issue_class=f"issue-sev-{issue.severity.lower()}", test_name=issue.test, test_id=issue.test_id, test_text=issue.text, severity=issue.severity, cwe=issue.cwe, confidence=issue.confidence, path=issue.fname, code=code, candidates=candidates, url=url, line_number=issue.lineno, ) # build the metrics string to insert in the report metrics_summary = metrics_block.format( loc=manager.metrics.data["_totals"]["loc"], nosec=manager.metrics.data["_totals"]["nosec"], ) # build the report and output it report_contents = report_block.format(metrics=metrics_summary, skipped=skipped_text, results=results_str) with fileobj: wrapped_file = utils.wrap_file_object(fileobj) wrapped_file.write(header_block) wrapped_file.write(report_contents) if fileobj.name != sys.stdout.name: LOG.info("HTML output written to file: %s", fileobj.name)
def test_import_call_bib(self): expected_url = BASE_URL + ("blacklists/blacklist_imports.html" "#b413-import-pycrypto") self.assertEqual(expected_url, get_url('B413'))
def test_plugin_call_bib(self): expected_url = BASE_URL + "plugins/b101_assert_used.html" self.assertEqual(expected_url, get_url('B101'))
def test_overwrite_bib_info(self): expected_url = BASE_URL + ("blacklists/blacklist_calls.html" "#b304-b305-ciphers-and-modes") self.assertEqual(get_url('B304'), get_url('B305')) self.assertEqual(expected_url, get_url('B304'))
def report(manager, fileobj, sev_level, conf_level, lines=-1): """Writes issues to 'fileobj' in HTML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ header_block = u""" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> Bandit Report </title> <style> html * { font-family: "Arial", sans-serif; } pre { font-family: "Monaco", monospace; } .bordered-box { border: 1px solid black; padding-top:.5em; padding-bottom:.5em; padding-left:1em; } .metrics-box { font-size: 1.1em; line-height: 130%; } .metrics-title { font-size: 1.5em; font-weight: 500; margin-bottom: .25em; } .issue-description { font-size: 1.3em; font-weight: 500; } .candidate-issues { margin-left: 2em; border-left: solid 1px; LightGray; padding-left: 5%; margin-top: .2em; margin-bottom: .2em; } .issue-block { border: 1px solid LightGray; padding-left: .5em; padding-top: .5em; padding-bottom: .5em; margin-bottom: .5em; } .issue-sev-high { background-color: Pink; } .issue-sev-medium { background-color: NavajoWhite; } .issue-sev-low { background-color: LightCyan; } </style> </head> """ report_block = u""" <body> {metrics} {skipped} <br> <div id="results"> {results} </div> </body> </html> """ issue_block = u""" <div id="issue-{issue_no}"> <div class="issue-block {issue_class}"> <b>{test_name}: </b> {test_text}<br> <b>Test ID:</b> {test_id}<br> <b>Severity: </b>{severity}<br> <b>Confidence: </b>{confidence}<br> <b>File: </b><a href="{path}" target="_blank">{path}</a> <br> <b>More info: </b><a href="{url}" target="_blank">{url}</a><br> {code} {candidates} </div> </div> """ code_block = u""" <div class="code"> <pre> {code} </pre> </div> """ candidate_block = u""" <div class="candidates"> <br> <b>Candidates: </b> {candidate_list} </div> """ candidate_issue = u""" <div class="candidate"> <div class="candidate-issues"> <pre>{code}</pre> </div> </div> """ skipped_block = u""" <br> <div id="skipped"> <div class="bordered-box"> <b>Skipped files:</b><br><br> {files_list} </div> </div> """ metrics_block = u""" <div id="metrics"> <div class="metrics-box bordered-box"> <div class="metrics-title"> Metrics:<br> </div> Total lines of code: <span id="loc">{loc}</span><br> Total lines skipped (#nosec): <span id="nosec">{nosec}</span> </div> </div> """ issues = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(issues, list) # build the skipped string to insert in the report skipped_str = ''.join('%s <b>reason:</b> %s<br>' % (fname, reason) for fname, reason in manager.get_skipped()) if skipped_str: skipped_text = skipped_block.format(files_list=skipped_str) else: skipped_text = '' # build the results string to insert in the report results_str = '' for index, issue in enumerate(issues): if not baseline or len(issues[issue]) == 1: candidates = '' safe_code = cgi.escape(issue.get_code(lines, True). strip('\n').lstrip(' ')) code = code_block.format(code=safe_code) else: candidates_str = '' code = '' for candidate in issues[issue]: candidate_code = cgi.escape(candidate.get_code(lines, True). strip('\n').lstrip(' ')) candidates_str += candidate_issue.format(code=candidate_code) candidates = candidate_block.format(candidate_list=candidates_str) url = docs_utils.get_url(issue.test_id) results_str += issue_block.format(issue_no=index, issue_class='issue-sev-{}'. format(issue.severity.lower()), test_name=issue.test, test_id=issue.test_id, test_text=issue.text, severity=issue.severity, confidence=issue.confidence, path=issue.fname, code=code, candidates=candidates, url=url) # build the metrics string to insert in the report metrics_summary = metrics_block.format( loc=manager.metrics.data['_totals']['loc'], nosec=manager.metrics.data['_totals']['nosec']) # build the report and output it report_contents = report_block.format(metrics=metrics_summary, skipped=skipped_text, results=results_str) with fileobj: wrapped_file = utils.wrap_file_object(fileobj) wrapped_file.write(utils.convert_file_contents(header_block)) wrapped_file.write(utils.convert_file_contents(report_contents)) if fileobj.name != sys.stdout.name: LOG.info("HTML output written to file: %s", fileobj.name)