Skip to content

Commit

Permalink
Use shlex.quote for quoting shell arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
jwodder authored and davidism committed Feb 24, 2020
1 parent 59a4530 commit e798f64
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Unreleased
distinguish it from the next option. :issue:`1075`
- Consider ``sensible-editor`` when determining the editor to use for
``click.edit()``. :pr:`1469`
- Arguments to system calls such as the executable path passed to
``click.edit`` can contains spaces. :pr:`1470`


Version 7.0
Expand Down
4 changes: 4 additions & 0 deletions click/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ def seekable(self):
iteritems = lambda x: x.iteritems()
range_type = xrange

from pipes import quote as shlex_quote

def is_bytes(x):
return isinstance(x, (buffer, bytearray))

Expand Down Expand Up @@ -268,6 +270,8 @@ def filename_to_ui(value):
isidentifier = lambda x: x.isidentifier()
iteritems = lambda x: iter(x.items())

from shlex import quote as shlex_quote

def is_bytes(x):
return isinstance(x, (bytes, memoryview, bytearray))

Expand Down
28 changes: 14 additions & 14 deletions click/_termui_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
import time
import math
import contextlib
from ._compat import _default_text_stdout, range_type, PY2, isatty, \
open_stream, strip_ansi, term_len, get_best_encoding, WIN, int_types, \
CYGWIN
from ._compat import _default_text_stdout, range_type, isatty, \
open_stream, shlex_quote, strip_ansi, term_len, get_best_encoding, WIN, \
int_types, CYGWIN
from .utils import echo
from .exceptions import ClickException

Expand Down Expand Up @@ -328,7 +328,7 @@ def pager(generator, color=None):
fd, filename = tempfile.mkstemp()
os.close(fd)
try:
if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
if hasattr(os, 'system') and os.system("more %s" % shlex_quote(filename)) == 0:
return _pipepager(generator, 'more', color)
return _nullpager(stdout, generator, color)
finally:
Expand Down Expand Up @@ -396,7 +396,7 @@ def _tempfilepager(generator, cmd, color):
with open_stream(filename, 'wb')[0] as f:
f.write(text.encode(encoding))
try:
os.system(cmd + ' "' + filename + '"')
os.system("%s %s" % (shlex_quote(cmd), shlex_quote(filename)))
finally:
os.unlink(filename)

Expand Down Expand Up @@ -441,8 +441,11 @@ def edit_file(self, filename):
else:
environ = None
try:
c = subprocess.Popen('%s "%s"' % (editor, filename),
env=environ, shell=True)
c = subprocess.Popen(
"%s %s" % (shlex_quote(editor), shlex_quote(filename)),

This comment has been minimized.

Copy link
@dufferzafar

dufferzafar Mar 28, 2020

This brings in the following regression:

click.edit fails when I try to use VS Code as my editor:

>>> click.edit(editor='code-insiders -w')

/bin/sh: code-insiders -w: command not found

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/site-packages/click/termui.py", line 587, in edit
    return editor.edit(text)
  File "/usr/lib/python3.8/site-packages/click/_termui_impl.py", line 497, in edit
    self.edit_file(name)
  File "/usr/lib/python3.8/site-packages/click/_termui_impl.py", line 472, in edit_file
    raise ClickException("{}: Editing failed!".format(editor))
click.exceptions.ClickException: code-insiders -w: Editing failed!

Related to #119

env=environ,
shell=True
)
exit_code = c.wait()
if exit_code != 0:
raise ClickException('%s: Editing failed!' % editor)
Expand Down Expand Up @@ -513,19 +516,16 @@ def _unquote_file(url):
elif WIN:
if locate:
url = _unquote_file(url)
args = 'explorer /select,"%s"' % _unquote_file(
url.replace('"', ''))
args = "explorer /select,%s" % (shlex_quote(url),)
else:
args = 'start %s "" "%s"' % (
wait and '/WAIT' or '', url.replace('"', ''))
args = 'start %s "" %s' % ("/WAIT" if wait else "", shlex_quote(url))
return os.system(args)
elif CYGWIN:
if locate:
url = _unquote_file(url)
args = 'cygstart "%s"' % (os.path.dirname(url).replace('"', ''))
args = "cygstart %s" % (shlex_quote(os.path.dirname(url)),)
else:
args = 'cygstart %s "%s"' % (
wait and '-w' or '', url.replace('"', ''))
args = "cygstart %s %s" % ("-w" if wait else "", shlex_quote(url))
return os.system(args)

try:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def tracking_import(module, locals=None, globals=None, fromlist=None,
ALLOWED_IMPORTS = set([
'weakref', 'os', 'struct', 'collections', 'sys', 'contextlib',
'functools', 'stat', 're', 'codecs', 'inspect', 'itertools', 'io',
'threading', 'colorama', 'errno', 'fcntl', 'datetime'
'threading', 'colorama', 'errno', 'fcntl', 'datetime', 'pipes', 'shlex'
])

if WIN:
Expand Down

0 comments on commit e798f64

Please sign in to comment.