Detect binary output file (txt/html)

Printing out bytes values to text destination results in mangled
output. Add better detection.

Closes-bug: 1613169
Co-Authored-By: Ian Cordasco <graffatcolmingov@gmail.com>
Change-Id: I6e08cea789e13b71f6e70fbe991026b75be80199
This commit is contained in:
Stanisław Pitucha 2016-08-15 15:35:23 +10:00 committed by Ian Cordasco
parent 3cf14c773e
commit 01211464e3
3 changed files with 50 additions and 3 deletions

View File

@ -152,6 +152,7 @@ import sys
from bandit.core import docs_utils
from bandit.core import test_properties
from bandit.formatters import utils
LOG = logging.getLogger(__name__)
@ -372,8 +373,9 @@ pre {
results=results_str)
with fileobj:
fileobj.write(str(header_block.encode('utf-8')))
fileobj.write(str(report_contents.encode('utf-8')))
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)

View File

@ -45,6 +45,7 @@ import sys
from bandit.core import constants
from bandit.core import test_properties
from bandit.formatters import utils
LOG = logging.getLogger(__name__)
@ -155,7 +156,8 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
result = '\n'.join([bit for bit in bits]) + '\n'
with fileobj:
fileobj.write(str(result.encode('utf-8')))
wrapped_file = utils.wrap_file_object(fileobj)
wrapped_file.write(utils.convert_file_contents(result))
if fileobj.name != sys.stdout.name:
LOG.info("Text output written to file: %s", fileobj.name)

View File

@ -0,0 +1,43 @@
# Copyright (c) 2016 Rackspace, Inc.
#
# 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.
"""Utility functions for formatting plugins for Bandit."""
import io
import six
def wrap_file_object(fileobj):
"""Handle differences in Python 2 and 3 around writing bytes."""
# If it's not an instance of IOBase, we're probably using Python 2 and
# that is less finnicky about writing text versus bytes to a file.
if not isinstance(fileobj, io.IOBase):
return fileobj
# At this point we're using Python 3 and that will mangle text written to
# a file written in bytes mode. So, let's check if the file can handle
# text as opposed to bytes.
if isinstance(fileobj, io.TextIOBase):
return fileobj
# Finally, we've determined that the fileobj passed in cannot handle text,
# so we use TextIOWrapper to handle the conversion for us.
return io.TextIOWrapper(fileobj)
def convert_file_contents(text):
"""Convert text to built-in strings on Python 2."""
if not six.PY2:
return text
return str(text.encode('utf-8'))