Skip to content

Commit

Permalink
More complete removal of Python2 code (#674)
Browse files Browse the repository at this point in the history
* Removes six imports and six.Py2 conditionals
* Merged example files (e.g exec-py2.py|exec-py3.py > exec.py)
* Removes unnecessary workarounds for Py2 bugs

Fixes #584

Signed-off-by: Eric Brown <browne@vmware.com>
  • Loading branch information
ericwb committed Dec 19, 2020
1 parent 5f07310 commit c9aa204
Show file tree
Hide file tree
Showing 26 changed files with 49 additions and 186 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,9 @@ using RST::
Under Which Version of Python Should I Install Bandit?
------------------------------------------------------
The answer to this question depends on the project(s) you will be running
Bandit against. If your project is only compatible with Python 2.7, you
should install Bandit to run under Python 2.7. If your project is only
compatible with Python 3.5, then use 3.5 respectively. If your project supports
Bandit against. If your project is only compatible with Python 3.5, you
should install Bandit to run under Python 3.5. If your project is only
compatible with Python 3.8, then use 3.8 respectively. If your project supports
both, you *could* run Bandit with both versions but you don't have to.

Bandit uses the `ast` module from Python's standard library in order to
Expand Down
10 changes: 2 additions & 8 deletions bandit/core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import ast

import six

from bandit.core import utils


Expand Down Expand Up @@ -211,14 +209,10 @@ def _get_literal_value(self, literal):
elif isinstance(literal, ast.Name):
literal_value = literal.id

# NOTE(sigmavirus24): NameConstants are only part of the AST in Python
# 3. NameConstants tend to refer to things like True and False. This
# prevents them from being re-assigned in Python 3.
elif six.PY3 and isinstance(literal, ast.NameConstant):
elif isinstance(literal, ast.NameConstant):
literal_value = str(literal.value)

# NOTE(sigmavirus24): Bytes are only part of the AST in Python 3
elif six.PY3 and isinstance(literal, ast.Bytes):
elif isinstance(literal, ast.Bytes):
literal_value = literal.s

else:
Expand Down
3 changes: 1 addition & 2 deletions bandit/core/extension_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import sys

import six
from stevedore import extension

from bandit.core import utils
Expand Down Expand Up @@ -75,7 +74,7 @@ def load_blacklists(self, blacklist_namespace):

self.blacklist_by_id = {}
self.blacklist_by_name = {}
for val in six.itervalues(self.blacklist):
for val in self.blacklist.values():
for b in val:
self.blacklist_by_id[b['id']] = b
self.blacklist_by_name[b['name']] = b
Expand Down
4 changes: 1 addition & 3 deletions bandit/core/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

import linecache

from six import moves

from bandit.core import constants


Expand Down Expand Up @@ -84,7 +82,7 @@ def get_code(self, max_lines=3, tabbed=False):
lmax = lmin + len(self.linerange) + max_lines - 1

tmplt = "%i\t%s" if tabbed else "%i %s"
for line in moves.xrange(lmin, lmax):
for line in range(lmin, lmax):
text = linecache.getline(self.fname, line)

if isinstance(text, bytes):
Expand Down
7 changes: 1 addition & 6 deletions bandit/core/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import tokenize
import traceback

import six

from bandit.core import constants as b_constants
from bandit.core import extension_loader
from bandit.core import issue
Expand Down Expand Up @@ -280,10 +278,7 @@ def _parse_file(self, fname, fdata, new_files_list):
else:
try:
fdata.seek(0)
if six.PY2:
tokens = tokenize.generate_tokens(fdata.readline)
else:
tokens = tokenize.tokenize(fdata.readline)
tokens = tokenize.tokenize(fdata.readline)
nosec_lines = set(
lineno for toktype, tokval, (lineno, _), _, _ in tokens
if toktype == tokenize.COMMENT and
Expand Down
11 changes: 3 additions & 8 deletions bandit/formatters/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,14 @@
"""
from __future__ import absolute_import

from html import escape as html_escape
import logging
import sys

import six

from bandit.core import docs_utils
from bandit.core import test_properties
from bandit.formatters import utils

if not six.PY2:
from html import escape as html_escape
else:
from cgi import escape as html_escape

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -377,8 +372,8 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):

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))
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)
2 changes: 1 addition & 1 deletion bandit/formatters/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):

with fileobj:
wrapped_file = utils.wrap_file_object(fileobj)
wrapped_file.write(utils.convert_file_contents(result))
wrapped_file.write(result)

if fileobj.name != sys.stdout.name:
LOG.info("Text output written to file: %s", fileobj.name)
9 changes: 0 additions & 9 deletions bandit/formatters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import io

import six


def wrap_file_object(fileobj):
"""Handle differences in Python 2 and 3 around writing bytes."""
Expand All @@ -24,10 +22,3 @@ def wrap_file_object(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'))
7 changes: 1 addition & 6 deletions bandit/formatters/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
import sys
from xml.etree import cElementTree as ET

import six

from bandit.core import docs_utils

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -71,10 +69,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
tree = ET.ElementTree(root)

if fileobj.name == sys.stdout.name:
if six.PY2:
fileobj = sys.stdout
else:
fileobj = sys.stdout.buffer
fileobj = sys.stdout.buffer
elif fileobj.mode == 'w':
fileobj.close()
fileobj = open(fileobj.name, "wb")
Expand Down
45 changes: 8 additions & 37 deletions bandit/plugins/django_xss.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import ast

import six

import bandit
from bandit.core import test_properties as test

Expand Down Expand Up @@ -45,28 +43,13 @@ def is_assigned(self, node):
return assigned
assigned = self.is_assigned_in(node.body)
elif isinstance(node, ast.With):
if six.PY2:
if node.optional_vars.id == self.var_name.id:
for withitem in node.items:
var_id = getattr(withitem.optional_vars, 'id', None)
if var_id == self.var_name.id:
assigned = node
else:
assigned = self.is_assigned_in(node.body)
else:
for withitem in node.items:
var_id = getattr(withitem.optional_vars, 'id', None)
if var_id == self.var_name.id:
assigned = node
else:
assigned = self.is_assigned_in(node.body)
elif six.PY2 and isinstance(node, ast.TryFinally):
assigned = []
assigned.extend(self.is_assigned_in(node.body))
assigned.extend(self.is_assigned_in(node.finalbody))
elif six.PY2 and isinstance(node, ast.TryExcept):
assigned = []
assigned.extend(self.is_assigned_in(node.body))
assigned.extend(self.is_assigned_in(node.handlers))
assigned.extend(self.is_assigned_in(node.orelse))
elif not six.PY2 and isinstance(node, ast.Try):
elif isinstance(node, ast.Try):
assigned = []
assigned.extend(self.is_assigned_in(node.body))
assigned.extend(self.is_assigned_in(node.handlers))
Expand Down Expand Up @@ -103,8 +86,7 @@ def evaluate_var(xss_var, parent, until, ignore_nodes=None):
if isinstance(xss_var, ast.Name):
if isinstance(parent, ast.FunctionDef):
for name in parent.args.args:
arg_name = name.id if six.PY2 else name.arg
if arg_name == xss_var.id:
if name.arg == xss_var.id:
return False # Params are not secure

analyser = DeepAssignation(xss_var, ignore_nodes)
Expand Down Expand Up @@ -150,15 +132,11 @@ def evaluate_call(call, parent, ignore_nodes=None):
if isinstance(call, ast.Call) and isinstance(call.func, ast.Attribute):
if isinstance(call.func.value, ast.Str) and call.func.attr == 'format':
evaluate = True
if call.keywords or (six.PY2 and call.kwargs):
if call.keywords:
evaluate = False # TODO(??) get support for this

if evaluate:
args = list(call.args)
if six.PY2 and call.starargs and isinstance(call.starargs,
(ast.List, ast.Tuple)):
args.extend(call.starargs.elts)

num_secure = 0
for arg in args:
if isinstance(arg, ast.Str):
Expand All @@ -173,7 +151,7 @@ def evaluate_call(call, parent, ignore_nodes=None):
num_secure += 1
else:
break
elif not six.PY2 and isinstance(arg, ast.Starred) and isinstance(
elif isinstance(arg, ast.Starred) and isinstance(
arg.value, (ast.List, ast.Tuple)):
args.extend(arg.value.elts)
num_secure += 1
Expand All @@ -192,19 +170,13 @@ def transform2call(var):
new_call = ast.Call()
new_call.args = []
new_call.args = []
if six.PY2:
new_call.starargs = None
new_call.keywords = None
if six.PY2:
new_call.kwargs = None
new_call.lineno = var.lineno
new_call.func = ast.Attribute()
new_call.func.value = var.left
new_call.func.attr = 'format'
if isinstance(var.right, ast.Tuple):
new_call.args = var.right.elts
elif six.PY2 and isinstance(var.right, ast.Dict):
new_call.kwargs = var.right
else:
new_call.args = [var.right]
return new_call
Expand All @@ -225,8 +197,7 @@ def check_risk(node):
is_param = False
if isinstance(parent, ast.FunctionDef):
for name in parent.args.args:
arg_name = name.id if six.PY2 else name.arg
if arg_name == xss_var.id:
if name.arg == xss_var.id:
is_param = True
break

Expand Down
18 changes: 5 additions & 13 deletions bandit/plugins/exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
>> Issue: Use of exec detected.
Severity: Medium Confidence: High
Location: ./examples/exec-py2.py:2
Location: ./examples/exec.py:2
1 exec("do evil")
2 exec "do evil"
Expand All @@ -32,8 +32,6 @@
.. versionadded:: 0.9.0
"""

import six

import bandit
from bandit.core import test_properties as test

Expand All @@ -46,14 +44,8 @@ def exec_issue():
)


if six.PY2:
@test.checks('Exec')
@test.test_id('B102')
def exec_used(context):
@test.checks('Call')
@test.test_id('B102')
def exec_used(context):
if context.call_function_name_qual == 'exec':
return exec_issue()
else:
@test.checks('Call')
@test.test_id('B102')
def exec_used(context):
if context.call_function_name_qual == 'exec':
return exec_issue()
4 changes: 2 additions & 2 deletions bandit/plugins/general_bad_file_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
>> Issue: Probable insecure usage of temp file/directory.
Severity: Medium Confidence: Medium
Location: ./examples/os-chmod-py2.py:15
Location: ./examples/os-chmod.py:15
14 os.chmod('/etc/hosts', 0o777)
15 os.chmod('/tmp/oh_hai', 0x1ff)
16 os.chmod('/etc/passwd', stat.S_IRWXU)
>> Issue: Chmod setting a permissive mask 0777 on file (key_file).
Severity: High Confidence: High
Location: ./examples/os-chmod-py2.py:17
Location: ./examples/os-chmod.py:17
16 os.chmod('/etc/passwd', stat.S_IRWXU)
17 os.chmod(key_file, 0o777)
18
Expand Down
9 changes: 2 additions & 7 deletions bandit/plugins/general_hardcoded_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import ast
import re
import sys

import bandit
from bandit.core import test_properties as test
Expand Down Expand Up @@ -205,10 +204,6 @@ def hardcoded_password_default(context):

# go through all (param, value)s and look for candidates
for key, val in zip(context.node.args.args, defs):
py3_is_arg = True
if sys.version_info.major > 2:
py3_is_arg = isinstance(key, ast.arg)
if isinstance(key, ast.Name) or py3_is_arg:
check = key.arg if sys.version_info.major > 2 else key.id # Py3
if isinstance(val, ast.Str) and RE_CANDIDATES.search(check):
if isinstance(key, (ast.Name, ast.arg)):
if isinstance(val, ast.Str) and RE_CANDIDATES.search(key.arg):
return _report(val.s)
4 changes: 1 addition & 3 deletions bandit/plugins/injection_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import ast
import re

import six

import bandit
from bandit.core import test_properties as test

Expand Down Expand Up @@ -91,7 +89,7 @@ def has_shell(context):
result = bool(val.keys)
elif isinstance(val, ast.Name) and val.id in ['False', 'None']:
result = False
elif not six.PY2 and isinstance(val, ast.NameConstant):
elif isinstance(val, ast.NameConstant):
result = val.value
else:
result = True
Expand Down
2 changes: 0 additions & 2 deletions examples/exec-py2.py

This file was deleted.

File renamed without changes.
17 changes: 0 additions & 17 deletions examples/os-chmod-py2.py

This file was deleted.

File renamed without changes.

0 comments on commit c9aa204

Please sign in to comment.