Adjust shell_escape to maybe work on windows

This commit is contained in:
Florian Bruhin 2014-05-05 11:09:10 +02:00
parent 85c4bb823f
commit 3b75bbf495
2 changed files with 25 additions and 17 deletions

View File

@ -419,6 +419,7 @@ class CurCommandDispatcher(QObject):
""" """
url = urlutils.urlstring(self._tabs.currentWidget().url()) url = urlutils.urlstring(self._tabs.currentWidget().url())
cmd = cmd.replace('{}', shell_escape(url)) cmd = cmd.replace('{}', shell_escape(url))
logging.debug("Executing: {}".format(cmd))
subprocess.Popen(cmd, shell=True) subprocess.Popen(cmd, shell=True)
@cmdutils.register(instance='mainwindow.tabs.cur', modes=['insert'], @cmdutils.register(instance='mainwindow.tabs.cur', modes=['insert'],

View File

@ -18,6 +18,7 @@
"""Other utilities which don't fit anywhere else.""" """Other utilities which don't fit anywhere else."""
import re import re
import sys
import shlex import shlex
from functools import reduce from functools import reduce
from pkg_resources import resource_string from pkg_resources import resource_string
@ -80,26 +81,32 @@ def safe_shlex_split(s):
def shell_escape(s): def shell_escape(s):
"""Escape a string so it's safe to pass to a shell. """Escape a string so it's safe to pass to a shell."""
if sys.platform == 'win32':
Backported from python's shlex because that's only available since 3.3 and # Oh dear flying sphagetti monster please kill me now...
we might want to support 3.2. if not s:
# Is this an empty argument or a literal ""? It seems to depend on
FIXME: Make this work correctly in Windows, but I'd probably rather kill # something magical.
myself. [1] might help. return '""'
# We could also use \", but what do we do for a literal \" then? It
[1] https://en.wikibooks.org/wiki/Windows_Batch_Scripting#How_a_command_line_is_interpreted # seems \\\". But \\ anywhere else is a literal \\. Because that makes
""" # sense. Totally NOT. Using """ also seems to yield " and work in some
try: # kind-of-safe manner.
return shlex.quote(s) s.replace('"', '"""')
except AttributeError: # Some places suggest we use %% to escape %, but actually ^% seems to
_find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search # work better (compare echo %%DATE%% and echo ^%DATE^%)
s = re.sub(r'[&|^><%]', r'^\g<0>', s)
# Is everything escaped now? Maybe. I don't know. I don't *get* the
# black magic Microshit is doing here.
return s
else:
# Backported from python's shlex because that's only available since
# 3.3 and we might want to support 3.2.
find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search
if not s: if not s:
return "''" return "''"
if _find_unsafe(s) is None: if find_unsafe(s) is None:
return s return s
# use single quotes, and put single quotes into double quotes # use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b' # the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'" return "'" + s.replace("'", "'\"'\"'") + "'"