From: Neraste Date: Wed, 13 Jun 2018 07:07:04 +0000 (+0200) Subject: Ignore symbolic links pointing outside of the root directory (#339) X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/42a3fe53319a8c02858c2a96989ed1339f84515a?ds=inline;hp=fb34c9e19589d05f92084a28940837151251ebd6 Ignore symbolic links pointing outside of the root directory (#339) Fixes #338 --- diff --git a/black.py b/black.py index 9d9bada..e3b3882 100644 --- a/black.py +++ b/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(): - 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(): normalized_path += "/" exclude_match = exclude.search(normalized_path) diff --git a/tests/test_black.py b/tests/test_black.py index 84b7a61..3418df9 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -11,7 +11,7 @@ import sys 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 @@ class BlackTestCase(unittest.TestCase): 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")