diff options
| author | say <[email protected]> | 2022-05-17 00:30:24 +0300 | 
|---|---|---|
| committer | say <[email protected]> | 2022-05-17 00:30:24 +0300 | 
| commit | 3fddaa3192396d921374ef959a73169c47d34af5 (patch) | |
| tree | ea125fa2430421c42a018703a70f5ce94d98e866 | |
| parent | 45e5e9ae890daf63ba9a7a9550c1d64ac7e4734d (diff) | |
YMAKE-148: Don't follow symlinks
ref:b200b70556036c6a735ab81b1414c4b334ba5958
| -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 579a276d028..9a54e7f0f92 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 c01435f7dfd..09ade19043c 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)  | 
