# -*- coding:utf-8 -*- # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. r""" ============= XML Formatter ============= This formatter outputs the issues as XML. :Example: .. code-block:: xml Test ID: B301 Severity: MEDIUM Confidence: HIGH Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load(). Location examples/yaml_load.py:5 .. versionadded:: 0.12.0 """ # This future import is necessary here due to the xml import below on Python # 2.7 from __future__ import absolute_import import logging import sys from xml.etree import cElementTree as ET import six from bandit.core import docs_utils LOG = logging.getLogger(__name__) 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 Confidence: %s\n%s\nLocation %s:%s' text = text % (issue.test_id, issue.severity, 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: if six.PY2: fileobj = sys.stdout else: 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)