diff options
author | say <say@yandex-team.ru> | 2022-05-17 00:30:24 +0300 |
---|---|---|
committer | say <say@yandex-team.ru> | 2022-05-17 00:30:24 +0300 |
commit | 3fddaa3192396d921374ef959a73169c47d34af5 (patch) | |
tree | ea125fa2430421c42a018703a70f5ce94d98e866 /library/python | |
parent | 45e5e9ae890daf63ba9a7a9550c1d64ac7e4734d (diff) | |
download | ydb-3fddaa3192396d921374ef959a73169c47d34af5.tar.gz |
YMAKE-148: Don't follow symlinks
ref:b200b70556036c6a735ab81b1414c4b334ba5958
Diffstat (limited to 'library/python')
-rw-r--r-- | library/python/runtime_py3/importer.pxi | 13 | ||||
-rw-r--r-- | library/python/runtime_py3/test/test_arcadia_source_finder.py | 9 |
2 files changed, 17 insertions, 5 deletions
diff --git a/library/python/runtime_py3/importer.pxi b/library/python/runtime_py3/importer.pxi index 579a276d02..9a54e7f0f9 100644 --- a/library/python/runtime_py3/importer.pxi +++ b/library/python/runtime_py3/importer.pxi @@ -2,7 +2,7 @@ import marshal import sys from _codecs import utf_8_decode, utf_8_encode from _frozen_importlib import _call_with_frames_removed, spec_from_loader, BuiltinImporter -from _frozen_importlib_external import _os, _path_isfile, _path_isdir, _path_isabs, path_sep, _path_join, _path_split +from _frozen_importlib_external import _os, _path_isfile, _path_isabs, path_sep, _path_join, _path_split from _io import FileIO import __res as __resource @@ -402,6 +402,7 @@ class ArcadiaSourceFinder: NAMESPACE_PREFIX = b'py/namespace/' PY_EXT = '.py' YA_MAKE = 'ya.make' + S_IFDIR = 0o040000 def __init__(self, source_root): self.source_root = source_root @@ -470,12 +471,20 @@ class ArcadiaSourceFinder: elif dir_item.endswith(self.PY_EXT) and _path_isfile(_path_join(abs_path, dir_item)): yield prefix + dir_item[:-len(self.PY_EXT)], False + def _isdir(self, path): + """ Unlike _path_isdir() this function don't follow symlink """ + try: + stat_info = _os.lstat(path) + except OSError: + return False + return (stat_info.st_mode & 0o170000) == self.S_IFDIR + def _path_is_simple_dir(self, abs_path): """ Check if path is a directory but doesn't contain ya.make file. We don't want to steal directory from nested project and treat it as a package """ - return _path_isdir(abs_path) and not _path_isfile(_path_join(abs_path, self.YA_MAKE)) + return self._isdir(abs_path) and not _path_isfile(_path_join(abs_path, self.YA_MAKE)) def _find_module_in_paths(self, find_package_only, paths, module): """Auxiliary method. See _cache_module_path() for details""" diff --git a/library/python/runtime_py3/test/test_arcadia_source_finder.py b/library/python/runtime_py3/test/test_arcadia_source_finder.py index c01435f7df..09ade19043 100644 --- a/library/python/runtime_py3/test/test_arcadia_source_finder.py +++ b/library/python/runtime_py3/test/test_arcadia_source_finder.py @@ -1,5 +1,7 @@ +import stat import unittest import yaml +from collections import namedtuple from unittest.mock import patch from parameterized import parameterized @@ -17,9 +19,9 @@ class ImporterMocks(object): self._patchers = [ patch('__res.iter_keys', wraps=self._iter_keys), patch('__res.__resource.find', wraps=self._resource_find), - patch('__res._path_isdir', wraps=self._path_isdir), patch('__res._path_isfile', wraps=self._path_isfile), patch('__res._os.listdir', wraps=self._os_listdir), + patch('__res._os.lstat', wraps=self._os_lstat), ] for patcher in self._patchers: patcher.start() @@ -51,9 +53,10 @@ class ImporterMocks(object): f = self._lookup_mock_fs(filename) return isinstance(f, str) - def _path_isdir(self, filename): + def _os_lstat(self, filename): f = self._lookup_mock_fs(filename) - return isinstance(f, dict) + mode = stat.S_IFDIR if isinstance(f, dict) else stat.S_IFREG + return namedtuple('fake_stat_type', 'st_mode')(st_mode=mode) def _os_listdir(self, dirname): f = self._lookup_mock_fs(dirname) |