Ignore symbolic links pointing outside of the root directory (#339)
Fixes #338
This commit is contained in:
parent
fb34c9e195
commit
42a3fe5331
13
black.py
13
black.py
@ -2941,11 +2941,24 @@ def gen_python_files_in_dir(
|
||||
"""Generate all files under `path` whose paths are not excluded by the
|
||||
`exclude` regex, but are included by the `include` regex.
|
||||
|
||||
Symbolic links pointing outside of the root directory are ignored.
|
||||
|
||||
`report` is where output about exclusions goes.
|
||||
"""
|
||||
assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
|
||||
for child in path.iterdir():
|
||||
try:
|
||||
normalized_path = "/" + child.resolve().relative_to(root).as_posix()
|
||||
except ValueError:
|
||||
if child.is_symlink():
|
||||
report.path_ignored(
|
||||
child,
|
||||
"is a symbolic link that points outside of the root directory",
|
||||
)
|
||||
continue
|
||||
|
||||
raise
|
||||
|
||||
if child.is_dir():
|
||||
normalized_path += "/"
|
||||
exclude_match = exclude.search(normalized_path)
|
||||
|
@ -11,7 +11,7 @@
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Any, BinaryIO, Generator, List, Tuple, Iterator
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from click import unstyle
|
||||
from click.testing import CliRunner
|
||||
@ -1162,6 +1162,49 @@ def test_assert_equivalent_different_asts(self) -> None:
|
||||
with self.assertRaises(AssertionError):
|
||||
black.assert_equivalent("{}", "None")
|
||||
|
||||
def test_symlink_out_of_root_directory(self) -> None:
|
||||
# prepare argumens
|
||||
path = MagicMock()
|
||||
root = THIS_DIR
|
||||
child = MagicMock()
|
||||
include = re.compile(black.DEFAULT_INCLUDES)
|
||||
exclude = re.compile(black.DEFAULT_EXCLUDES)
|
||||
report = black.Report()
|
||||
|
||||
# set the behavior of mock arguments
|
||||
# child should behave like a symlink which resolved path is clearly
|
||||
# outside of the root directory
|
||||
path.iterdir.return_value = [child]
|
||||
child.resolve.return_value = Path("/a/b/c")
|
||||
child.is_symlink.return_value = True
|
||||
|
||||
# call the method
|
||||
# it should not raise any error
|
||||
list(black.gen_python_files_in_dir(path, root, include, exclude, report))
|
||||
|
||||
# check the call of the methods of the mock objects
|
||||
path.iterdir.assert_called_once()
|
||||
child.resolve.assert_called_once()
|
||||
child.is_symlink.assert_called_once()
|
||||
|
||||
# set the behavior of mock arguments
|
||||
# child should behave like a strange file which resolved path is clearly
|
||||
# outside of the root directory
|
||||
child.is_symlink.return_value = False
|
||||
|
||||
# call the method
|
||||
# it should raise a ValueError
|
||||
with self.assertRaises(ValueError):
|
||||
list(black.gen_python_files_in_dir(path, root, include, exclude, report))
|
||||
|
||||
# check the call of the methods of the mock objects
|
||||
path.iterdir.assert_called()
|
||||
self.assertEqual(path.iterdir.call_count, 2)
|
||||
child.resolve.assert_called()
|
||||
self.assertEqual(child.resolve.call_count, 2)
|
||||
child.is_symlink.assert_called()
|
||||
self.assertEqual(child.is_symlink.call_count, 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(module="test_black")
|
||||
|
Loading…
Reference in New Issue
Block a user