patch 9.2.0561: [security]: possible code execution with python3complete

Problem:  [security]: possible code execution with python3complete
Solution: Disable execution of import/from statements

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-52mc-rq6p-rc7c

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-05-29 19:05:53 +00:00
parent 69f402e97f
commit 4b850457e1
5 changed files with 44 additions and 6 deletions
+1
View File
@@ -17,6 +17,7 @@ htmlcomplete.vim HTML
javascriptcomplete.vim Javascript
phpcomplete.vim PHP
pythoncomplete.vim Python
python3complete.vim Python
rubycomplete.vim Ruby
syntaxcomplete.vim from syntax highlighting
xmlcomplete.vim XML (uses files in the xml directory)
+14 -3
View File
@@ -14,6 +14,10 @@
" i.e. "import url<c-x,c-o>"
" Continue parsing on invalid line??
"
" v 0.10 by Vim project
" * disables importing local modules, unless the global Vim variable
" g:pythoncomplete_allow_import is set to non-zero
"
" v 0.9
" * Fixed docstring parsing for classes and functions
" * Fixed parsing of *args and **kwargs type arguments
@@ -132,11 +136,20 @@ class Completer(object):
def evalsource(self,text,line=0):
sc = self.parser.parse(text,line)
try: allow_imports = int(
vim.eval("get(g:, 'pythoncomplete_allow_import', 0)"))
except Exception:
allow_imports = 0
src = sc.get_code()
dbg("source: %s" % src)
try: exec(src,self.compldict)
except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1]))
for l in sc.locals:
# Executing import/from statements harvested from the buffer runs
# arbitrary package code; only do so when the user opted in.
if not allow_imports and (l.startswith('import')
or l.startswith('from ')):
continue
try: exec(l,self.compldict)
except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l))
@@ -300,13 +313,11 @@ class Scope(object):
def get_code(self):
str = ""
if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
for l in self.locals:
if l.startswith('import'): str += l+'\n'
str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n'
for sub in self.subscopes:
str += sub.get_code()
for l in self.locals:
if not l.startswith('import'): str += l+'\n'
if not l.startswith('import') and not l.startswith('from '): str += l+'\n'
return str
+14 -3
View File
@@ -12,6 +12,10 @@
" i.e. "import url<c-x,c-o>"
" Continue parsing on invalid line??
"
" v 0.10 by Vim project
" * disables importing local modules, unless the global Vim variable
" g:pythoncomplete_allow_import is set to non-zero
"
" v 0.9
" * Fixed docstring parsing for classes and functions
" * Fixed parsing of *args and **kwargs type arguments
@@ -146,11 +150,20 @@ class Completer(object):
def evalsource(self,text,line=0):
sc = self.parser.parse(text,line)
try: allow_imports = int(
vim.eval("get(g:, 'pythoncomplete_allow_import', 0)"))
except Exception:
allow_imports = 0
src = sc.get_code()
dbg("source: %s" % src)
try: exec(src) in self.compldict
except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1]))
for l in sc.locals:
# Executing import/from statements harvested from the buffer runs
# arbitrary package code; only do so when the user opted in.
if not allow_imports and (l.startswith('import')
or l.startswith('from ')):
continue
try: exec(l) in self.compldict
except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l))
@@ -315,13 +328,11 @@ class Scope(object):
def get_code(self):
str = ""
if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
for l in self.locals:
if l.startswith('import'): str += l+'\n'
str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n'
for sub in self.subscopes:
str += sub.get_code()
for l in self.locals:
if not l.startswith('import'): str += l+'\n'
if not l.startswith('import') and not l.startswith('from '): str += l+'\n'
return str
+13
View File
@@ -976,7 +976,20 @@ By default the following options are set, in accordance with PEP8: >
To disable this behavior, set the following variable in your vimrc: >
let g:python_recommended_style = 0
<
Python omni-completion |compl-omni| is provided by python3complete.vim (or
pythoncomplete.vim) for Vim builds with the |+python|/|+python3| interpreter.
By default it does not inspect the import / from statements found in the
buffer. This means completion of names defined in the buffer itself (classes,
functions, variables) works, but completion of members of imported modules is
not offered.
To enable completion of imported module members, set: >
let g:pythoncomplete_allow_import = 1
<
WARNING: enabling this causes omni-completion to execute the import statements
found in the buffer through Python's import machinery, which runs the imported
modules' top-level code. Only enable this for code you trust.
QF QUICKFIX *qf.vim* *ft-qf-plugin*
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
561,
/**/
560,
/**/