aboutsummaryrefslogtreecommitdiffstats
path: root/library/python
diff options
context:
space:
mode:
authorsay <say@yandex-team.ru>2022-05-17 00:30:24 +0300
committersay <say@yandex-team.ru>2022-05-17 00:30:24 +0300
commit3fddaa3192396d921374ef959a73169c47d34af5 (patch)
treeea125fa2430421c42a018703a70f5ce94d98e866 /library/python
parent45e5e9ae890daf63ba9a7a9550c1d64ac7e4734d (diff)
downloadydb-3fddaa3192396d921374ef959a73169c47d34af5.tar.gz
YMAKE-148: Don't follow symlinks
ref:b200b70556036c6a735ab81b1414c4b334ba5958
Diffstat (limited to 'library/python')
-rw-r--r--library/python/runtime_py3/importer.pxi13
-rw-r--r--library/python/runtime_py3/test/test_arcadia_source_finder.py9
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)