Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpret wildcards in the file exclusion list #450

Merged
merged 5 commits into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ Usage::
only show output in the case of an error
--ignore-nosec do not skip lines with # nosec comments
-x EXCLUDED_PATHS, --exclude EXCLUDED_PATHS
comma-separated list of paths to exclude from scan
(note that these are in addition to the excluded paths
provided in the config file)
comma-separated list of paths (glob patterns supported)
to exclude from scan (note that these are in addition
to the excluded paths provided in the config file)
-b BASELINE, --baseline BASELINE
path of a baseline report to compare against (only
JSON-formatted files are accepted)
Expand Down Expand Up @@ -289,7 +289,7 @@ Configuration
An optional config file may be supplied and may include:
- lists of tests which should or shouldn't be run
- exclude_dirs - sections of the path, that if matched, will be excluded from
scanning
scanning (glob patterns supported)
- overridden plugin settings - may provide different settings for some
plugins

Expand Down
3 changes: 2 additions & 1 deletion bandit/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ def main():
)
parser.add_argument(
'-x', '--exclude', dest='excluded_paths', action='store',
default='', help='comma-separated list of paths to exclude from scan '
default='', help='comma-separated list of paths (glob patterns '
'supported) to exclude from scan '
'(note that these are in addition to the excluded '
'paths provided in the config file)'
)
Expand Down
13 changes: 7 additions & 6 deletions bandit/core/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,13 @@ def discover_files(self, targets, recursive=False, excluded_paths=''):
files_list = set()
excluded_files = set()

excluded_path_strings = self.b_conf.get_option('exclude_dirs') or []
excluded_path_globs = self.b_conf.get_option('exclude_dirs') or []
included_globs = self.b_conf.get_option('include') or ['*.py']

# if there are command line provided exclusions add them to the list
if excluded_paths:
for path in excluded_paths.split(','):
excluded_path_strings.append(path)
excluded_path_globs.append(path)

# build list of files we will analyze
for fname in targets:
Expand All @@ -200,7 +200,7 @@ def discover_files(self, targets, recursive=False, excluded_paths=''):
new_files, newly_excluded = _get_files_from_dir(
fname,
included_globs=included_globs,
excluded_path_strings=excluded_path_strings
excluded_path_strings=excluded_path_globs
)
files_list.update(new_files)
excluded_files.update(newly_excluded)
Expand All @@ -213,7 +213,7 @@ def discover_files(self, targets, recursive=False, excluded_paths=''):
# we'll scan it, regardless of whether it's in the included
# file types list
if _is_file_included(fname, included_globs,
excluded_path_strings,
excluded_path_globs,
enforce_glob=False):
files_list.add(fname)
else:
Expand Down Expand Up @@ -353,7 +353,8 @@ def _is_file_included(path, included_globs, excluded_path_strings,

:param path: Full path of file to check
:param parsed_extensions: List of parsed extensions
:param excluded_paths: List of paths from which we should not include files
:param excluded_paths: List of paths (globbing supported) from which we
should not include files
:param enforce_glob: Can set to false to bypass extension check
:return: Boolean indicating whether a file should be included
'''
Expand All @@ -362,7 +363,7 @@ def _is_file_included(path, included_globs, excluded_path_strings,
# if this is matches a glob of files we look at, and it isn't in an
# excluded path
if _matches_glob_list(path, included_globs) or not enforce_glob:
if not any(x in path for x in excluded_path_strings):
if not _matches_glob_list(path, excluded_path_strings):
return_value = True

return return_value
Expand Down
6 changes: 3 additions & 3 deletions doc/source/man/bandit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ OPTIONS
only show output in the case of an error
--ignore-nosec do not skip lines with # nosec comments
-x EXCLUDED_PATHS, --exclude EXCLUDED_PATHS
comma-separated list of paths to exclude from scan
(note that these are in addition to the excluded paths
provided in the config file)
comma-separated list of paths (glob patterns supported)
to exclude from scan (note that these are in addition
to the excluded paths provided in the config file)
-b BASELINE, --baseline BASELINE
path of a baseline report to compare against (only
JSON-formatted files are accepted)
Expand Down
26 changes: 22 additions & 4 deletions tests/unit/core/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,34 @@ def test_matches_globlist(self):

def test_is_file_included(self):
a = manager._is_file_included(path='a.py', included_globs=['*.py'],
excluded_path_strings='',
excluded_path_strings=[],
enforce_glob=True)

b = manager._is_file_included(path='a.dd', included_globs=['*.py'],
excluded_path_strings='',
excluded_path_strings=[],
enforce_glob=False)

c = manager._is_file_included(path='a.py', included_globs=['*.py'],
excluded_path_strings='a.py',
excluded_path_strings=['a.py'],
enforce_glob=True)

d = manager._is_file_included(path='a.dd', included_globs=['*.py'],
excluded_path_strings='',
excluded_path_strings=[],
enforce_glob=True)

e = manager._is_file_included(path='x_a.py', included_globs=['*.py'],
excluded_path_strings=['x_*.py'],
enforce_glob=True)

f = manager._is_file_included(path='x.py', included_globs=['*.py'],
excluded_path_strings=['x_*.py'],
enforce_glob=True)
self.assertTrue(a)
self.assertTrue(b)
self.assertFalse(c)
self.assertFalse(d)
self.assertFalse(e)
self.assertTrue(f)

@mock.patch('os.walk')
def test_get_files_from_dir(self, os_walk):
Expand Down Expand Up @@ -209,6 +219,14 @@ def test_discover_files_exclude_cmdline(self, isdir):
m.assert_called_with('c', ['*.py', '*.pyw'], ['a', 'b'],
enforce_glob=False)

@mock.patch('os.path.isdir')
def test_discover_files_exclude_glob(self, isdir):
isdir.return_value = False
self.manager.discover_files(['a.py', 'test_a.py', 'test.py'], True,
excluded_paths='test_*.py')
self.assertEqual(['a.py', 'test.py'], self.manager.files_list)
self.assertEqual(['test_a.py'], self.manager.excluded_files)

@mock.patch('os.path.isdir')
def test_discover_files_include(self, isdir):
isdir.return_value = False
Expand Down