From 6be23a230908368e6c70b7b40028ea546717ddee Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Thu, 27 Feb 2020 22:40:13 -0500 Subject: [PATCH 1/2] Escape with double quotes instead of single quotes This takes us away from the standard shlex implementation. It is still not what you want on Windows (backslashes will not be understood), however it should do what you want in more situations (for example it supports spaces). --- scp.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scp.py b/scp.py index dc929de..aa880f0 100644 --- a/scp.py +++ b/scp.py @@ -14,21 +14,23 @@ import types -# this is quote from the shlex module, added in py3.3 -_find_unsafe = re.compile(br'[^\w@%+=:,./~-]').search +safe_shell_chars = set(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + b"abcdefghijklmnopqrstuvwxyz" + + b"0123456789" + + b"-+=/:.,%_") def _sh_quote(s): - """Return a shell-escaped version of the string `s`.""" - if not s: - return b"" - if _find_unsafe(s) is None: + r"""Given bl"a, returns "bl\\"a". + """ + if not s or any(c not in safe_shell_chars for c in s): + return b'"%s"' % (s.replace(b'\\', b'\\\\') + .replace(b'"', b'\\"') + .replace(b'`', b'\\`') + .replace(b'$', b'\\$')) + else: return s - # use single quotes, and put single quotes into double quotes - # the string $'b is then quoted as '$'"'"'b' - return b"'" + s.replace(b"'", b"'\"'\"'") + b"'" - # Unicode conversion functions; assume UTF-8 From 21e8fed9f26d4ae41ebd81ec5d84a92696178672 Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Thu, 27 Feb 2020 22:52:18 -0500 Subject: [PATCH 2/2] Fix syntax for Python 3.4 --- scp.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scp.py b/scp.py index aa880f0..5276897 100644 --- a/scp.py +++ b/scp.py @@ -24,10 +24,14 @@ def _sh_quote(s): r"""Given bl"a, returns "bl\\"a". """ if not s or any(c not in safe_shell_chars for c in s): - return b'"%s"' % (s.replace(b'\\', b'\\\\') - .replace(b'"', b'\\"') - .replace(b'`', b'\\`') - .replace(b'$', b'\\$')) + return ( + b'"' + + s.replace(b'\\', b'\\\\') + .replace(b'"', b'\\"') + .replace(b'`', b'\\`') + .replace(b'$', b'\\$') + + b'"' + ) else: return s