Skip to content

Commit

Permalink
🐛 Fix scanning files that don't exist
Browse files Browse the repository at this point in the history
When following a symlink, we just subtracted the `cwd`
from the path. This caused us to scan non-existant files.
  • Loading branch information
KevinHock committed Sep 23, 2019
1 parent 2cd5a2b commit 098e956
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 19 deletions.
30 changes: 17 additions & 13 deletions detect_secrets/core/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ def initialize(
for element in path:
if os.path.isdir(element):
if should_scan_all_files:
files_to_scan.extend(_get_files_recursively(element))
files_to_scan.extend(
_get_files_recursively(element),
)
else:
files = _get_git_tracked_files(element)
if files:
files_to_scan.extend(files)
files_to_scan.extend(
_get_git_tracked_files(element),
)
elif os.path.isfile(element):
files_to_scan.append(element)
else:
Expand All @@ -77,7 +79,7 @@ def initialize(
files_to_scan,
)

for file in files_to_scan:
for file in sorted(files_to_scan):
output.scan_file(file)

return output
Expand Down Expand Up @@ -279,6 +281,7 @@ def _get_git_tracked_files(rootdir='.'):
:rtype: set|None
:returns: filepaths to files which git currently tracks (locally)
"""
output = []
try:
with open(os.devnull, 'w') as fnull:
git_files = subprocess.check_output(
Expand All @@ -289,13 +292,13 @@ def _get_git_tracked_files(rootdir='.'):
],
stderr=fnull,
)

return set([
util.get_relative_path(rootdir, filename)
for filename in git_files.decode('utf-8').split()
])
for filename in git_files.decode('utf-8').split():
relative_path = util.get_relative_path_if_in_cwd(rootdir, filename)
if relative_path:
output.append(relative_path)
except subprocess.CalledProcessError:
return None
pass
return output


def _get_files_recursively(rootdir):
Expand All @@ -305,6 +308,7 @@ def _get_files_recursively(rootdir):
output = []
for root, _, files in os.walk(rootdir):
for filename in files:
output.append(util.get_relative_path(root, filename))

relative_path = util.get_relative_path_if_in_cwd(root, filename)
if relative_path:
output.append(relative_path)
return output
15 changes: 11 additions & 4 deletions detect_secrets/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,18 @@ def get_root_directory(): # pragma: no cover
)


def get_relative_path(root, path):
"""Returns relative path, after following symlinks."""
return os.path.realpath(
os.path.join(root, path),
def get_relative_path_if_in_cwd(root, filepath):
"""Returns relative path, after following symlinks,
if in current working directory.
:rtype: str|None
"""
filepath = os.path.realpath(
os.path.join(root, filepath),
)[len(os.getcwd() + '/'):]
if os.path.isfile(filepath):
return filepath
return None


def get_git_sha(path):
Expand Down
26 changes: 24 additions & 2 deletions tests/core/baseline_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,18 @@ def test_with_multiple_files(self):
assert 'test_data/files/tmp/file_with_secrets.py' in results

def test_with_multiple_non_existent_files(self):
results = self.get_results(path=['non-existent-file.A', 'non-existent-file.B'])

with mock.patch(
'detect_secrets.core.baseline.util.get_relative_path_if_in_cwd',
return_value=None,
):
results = self.get_results(
path=[
'non-existent-file.A',
'non-existent-file.B',
# Will be non-existant due to mock.patch
'test_data/files/tmp/',
],
)
# No expected results, because files don't exist
assert not results

Expand Down Expand Up @@ -163,6 +173,18 @@ def test_scan_all_files(self):
)
assert len(results.keys()) == 2

def test_scan_all_files_with_bad_symlinks(self):
with mock.patch(
'detect_secrets.core.baseline.util.get_relative_path_if_in_cwd',
return_value=None,
):
results = self.get_results(
# Will be non-existant due to mock.patch
path=['test_data/files'],
scan_all_files=True,
)
assert len(results.keys()) == 0


class TestGetSecretsNotInBaseline(object):

Expand Down
13 changes: 13 additions & 0 deletions tests/util_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ def test_get_git_sha():
assert util.get_git_sha('.') == GIT_REPO_SHA.decode('utf-8')


def test_get_relative_path_if_in_cwd():
with mock.patch(
'detect_secrets.util.os.path.isfile',
return_value=False,
):
assert (
util.get_relative_path_if_in_cwd(
'test_data',
'config.env',
) is None
)


@pytest.mark.parametrize(
'git_remotes_result, expected_urls',
[
Expand Down

0 comments on commit 098e956

Please sign in to comment.