Ignore symbolic links pointing outside of the root directory (#339)
Fixes #338
This commit is contained in:
parent
fb34c9e195
commit
42a3fe5331
15
black.py
15
black.py
@ -2941,11 +2941,24 @@ def gen_python_files_in_dir(
|
|||||||
"""Generate all files under `path` whose paths are not excluded by the
|
"""Generate all files under `path` whose paths are not excluded by the
|
||||||
`exclude` regex, but are included by the `include` regex.
|
`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.
|
`report` is where output about exclusions goes.
|
||||||
"""
|
"""
|
||||||
assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
|
assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
|
||||||
for child in path.iterdir():
|
for child in path.iterdir():
|
||||||
normalized_path = "/" + child.resolve().relative_to(root).as_posix()
|
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():
|
if child.is_dir():
|
||||||
normalized_path += "/"
|
normalized_path += "/"
|
||||||
exclude_match = exclude.search(normalized_path)
|
exclude_match = exclude.search(normalized_path)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from typing import Any, BinaryIO, Generator, List, Tuple, Iterator
|
from typing import Any, BinaryIO, Generator, List, Tuple, Iterator
|
||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
from click import unstyle
|
from click import unstyle
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
@ -1162,6 +1162,49 @@ def test_assert_equivalent_different_asts(self) -> None:
|
|||||||
with self.assertRaises(AssertionError):
|
with self.assertRaises(AssertionError):
|
||||||
black.assert_equivalent("{}", "None")
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main(module="test_black")
|
unittest.main(module="test_black")
|
||||||
|
Loading…
Reference in New Issue
Block a user