forked from VimPlug/jedi
Do binary comparisons to get virtualenvs working and not just venvs
This commit is contained in:
+42
-8
@@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import hashlib
|
||||||
|
import filecmp
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
# When dropping Python 2.7 support we should consider switching to
|
# When dropping Python 2.7 support we should consider switching to
|
||||||
@@ -30,6 +32,14 @@ class _BaseEnvironment(object):
|
|||||||
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
|
version_string = '%s.%s' % (self.version_info.major, self.version_info.minor)
|
||||||
return parso.load_grammar(version=version_string)
|
return parso.load_grammar(version=version_string)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _sha256(self):
|
||||||
|
try:
|
||||||
|
return self._hash
|
||||||
|
except AttributeError:
|
||||||
|
self._hash = _calculate_sha256_for_file(self.executable)
|
||||||
|
return self._hash
|
||||||
|
|
||||||
|
|
||||||
class _Environment(_BaseEnvironment):
|
class _Environment(_BaseEnvironment):
|
||||||
"""
|
"""
|
||||||
@@ -123,6 +133,14 @@ def _get_virtual_env_from_var():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def _calculate_sha256_for_file(path):
|
||||||
|
sha256 = hashlib.sha256()
|
||||||
|
with open(path, 'rb') as f:
|
||||||
|
for block in iter(lambda: f.read(filecmp.BUFSIZE), b''):
|
||||||
|
sha256.update(block)
|
||||||
|
return sha256.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def get_default_environment():
|
def get_default_environment():
|
||||||
"""
|
"""
|
||||||
Tries to return an active Virtualenv. If there is no VIRTUAL_ENV variable
|
Tries to return an active Virtualenv. If there is no VIRTUAL_ENV variable
|
||||||
@@ -302,15 +320,31 @@ def _is_safe(executable_path):
|
|||||||
# Resolve sym links. A venv typically is a symlink to a known Python
|
# Resolve sym links. A venv typically is a symlink to a known Python
|
||||||
# binary. Only virtualenvs copy symlinks around.
|
# binary. Only virtualenvs copy symlinks around.
|
||||||
real_path = os.path.realpath(executable_path)
|
real_path = os.path.realpath(executable_path)
|
||||||
if os.name == 'nt':
|
|
||||||
# Just check the list of known Python versions. If it's not in there,
|
|
||||||
# it's likely an attacker or some Python that was not properly
|
|
||||||
# installed in the system.
|
|
||||||
for environment in find_python_environments():
|
|
||||||
if environment.executable == real_path:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
if _is_unix_safe_simple(real_path):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Just check the list of known Python versions. If it's not in there,
|
||||||
|
# it's likely an attacker or some Python that was not properly
|
||||||
|
# installed in the system.
|
||||||
|
for environment in find_python_environments():
|
||||||
|
if environment.executable == real_path:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# If the versions don't match, just compare the binary files. If we
|
||||||
|
# don't do that, only venvs will be working and not virtualenvs.
|
||||||
|
# venvs are symlinks while virtualenvs are actual copies of the
|
||||||
|
# Python files.
|
||||||
|
# This still means that if the system Python is updated and the
|
||||||
|
# virtualenv's Python is not (which is probably never going to get
|
||||||
|
# upgraded), it will not work with Jedi. IMO that's fine, because
|
||||||
|
# people should just be using venv. ~ dave
|
||||||
|
if environment._sha256 == _calculate_sha256_for_file(real_path):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _is_unix_safe_simple(real_path):
|
||||||
if _is_unix_admin():
|
if _is_unix_admin():
|
||||||
# In case we are root, just be conservative and
|
# In case we are root, just be conservative and
|
||||||
# only execute known paths.
|
# only execute known paths.
|
||||||
|
|||||||
Reference in New Issue
Block a user