Files
Hotel-Booking/Backend/venv/lib/python3.12/site-packages/bandit/formatters/text.py
Iliyan Angelov 62c1fe5951 updates
2025-12-01 06:50:10 +02:00

201 lines
5.8 KiB
Python

# Copyright (c) 2015 Hewlett Packard Enterprise
#
# SPDX-License-Identifier: Apache-2.0
r"""
==============
Text Formatter
==============
This formatter outputs the issues as plain text.
:Example:
.. code-block:: none
>> Issue: [B301:blacklist_calls] Use of unsafe yaml load. Allows
instantiation of arbitrary objects. Consider yaml.safe_load().
Severity: Medium Confidence: High
CWE: CWE-20 (https://cwe.mitre.org/data/definitions/20.html)
More Info: https://bandit.readthedocs.io/en/latest/
Location: examples/yaml_load.py:5
4 ystr = yaml.dump({'a' : 1, 'b' : 2, 'c' : 3})
5 y = yaml.load(ystr)
6 yaml.dump(y)
.. versionadded:: 0.9.0
.. versionchanged:: 1.5.0
New field `more_info` added to output
.. versionchanged:: 1.7.3
New field `CWE` added to output
"""
import datetime
import logging
import sys
from bandit.core import constants
from bandit.core import docs_utils
from bandit.core import test_properties
from bandit.formatters import utils
LOG = logging.getLogger(__name__)
def get_verbose_details(manager):
bits = []
bits.append(f"Files in scope ({len(manager.files_list)}):")
tpl = "\t%s (score: {SEVERITY: %i, CONFIDENCE: %i})"
bits.extend(
[
tpl % (item, sum(score["SEVERITY"]), sum(score["CONFIDENCE"]))
for (item, score) in zip(manager.files_list, manager.scores)
]
)
bits.append(f"Files excluded ({len(manager.excluded_files)}):")
bits.extend([f"\t{fname}" for fname in manager.excluded_files])
return "\n".join([bit for bit in bits])
def get_metrics(manager):
bits = []
bits.append("\nRun metrics:")
for criteria, _ in constants.CRITERIA:
bits.append(f"\tTotal issues (by {criteria.lower()}):")
for rank in constants.RANKING:
bits.append(
"\t\t%s: %s"
% (
rank.capitalize(),
manager.metrics.data["_totals"][f"{criteria}.{rank}"],
)
)
return "\n".join([bit for bit in bits])
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(
f"{indent}>> Issue: [{issue.test_id}:{issue.test}] {issue.text}"
)
bits.append(
"%s Severity: %s Confidence: %s"
% (
indent,
issue.severity.capitalize(),
issue.confidence.capitalize(),
)
)
bits.append(f"{indent} CWE: {str(issue.cwe)}")
bits.append(f"{indent} More Info: {docs_utils.get_url(issue.test_id)}")
bits.append(
"%s Location: %s:%s:%s"
% (
indent,
issue.fname,
issue.lineno if show_lineno else "",
issue.col_offset if show_lineno else "",
)
)
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 get_results(manager, sev_level, conf_level, lines):
bits = []
issues = manager.get_issue_list(sev_level, conf_level)
baseline = not isinstance(issues, list)
candidate_indent = " " * 10
if not len(issues):
return "\tNo issues identified."
for issue in issues:
# if not a baseline or only one candidate we know the issue
if not baseline or len(issues[issue]) == 1:
bits.append(_output_issue_str(issue, "", lines=lines))
# otherwise show the finding and the candidates
else:
bits.append(
_output_issue_str(
issue, "", show_lineno=False, show_code=False
)
)
bits.append("\n-- Candidate Issues --")
for candidate in issues[issue]:
bits.append(
_output_issue_str(candidate, candidate_indent, lines=lines)
)
bits.append("\n")
bits.append("-" * 50)
return "\n".join([bit for bit in bits])
@test_properties.accepts_baseline
def report(manager, fileobj, sev_level, conf_level, lines=-1):
"""Prints discovered issues in the text 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
"""
bits = []
if not manager.quiet or manager.results_count(sev_level, conf_level):
bits.append(
f"Run started:{datetime.datetime.now(datetime.timezone.utc)}"
)
if manager.verbose:
bits.append(get_verbose_details(manager))
bits.append("\nTest results:")
bits.append(get_results(manager, sev_level, conf_level, lines))
bits.append("\nCode scanned:")
bits.append(
"\tTotal lines of code: %i"
% (manager.metrics.data["_totals"]["loc"])
)
bits.append(
"\tTotal lines skipped (#nosec): %i"
% (manager.metrics.data["_totals"]["nosec"])
)
bits.append(
"\tTotal potential issues skipped due to specifically being "
"disabled (e.g., #nosec BXXX): %i"
% (manager.metrics.data["_totals"]["skipped_tests"])
)
skipped = manager.get_skipped()
bits.append(get_metrics(manager))
bits.append(f"Files skipped ({len(skipped)}):")
bits.extend(["\t%s (%s)" % skip for skip in skipped])
result = "\n".join([bit for bit in bits]) + "\n"
with fileobj:
wrapped_file = utils.wrap_file_object(fileobj)
wrapped_file.write(result)
if fileobj.name != sys.stdout.name:
LOG.info("Text output written to file: %s", fileobj.name)