Commit 4341e54d authored by Georg Brandl's avatar Georg Brandl

#7507: quote "!" in pipes.quote(); it is a special character for some shells.

parent f8bff488
...@@ -263,11 +263,11 @@ def makepipeline(infile, steps, outfile): ...@@ -263,11 +263,11 @@ def makepipeline(infile, steps, outfile):
# Reliably quote a string as a single argument for /bin/sh # Reliably quote a string as a single argument for /bin/sh
_safechars = string.ascii_letters + string.digits + '!@%_-+=:,./' # Safe unquoted # Safe unquoted
_funnychars = '"`$\\' # Unsafe inside "double quotes" _safechars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./')
def quote(file): def quote(file):
''' return a shell-escaped version of the file string ''' """Return a shell-escaped version of the file string."""
for c in file: for c in file:
if c not in _safechars: if c not in _safechars:
break break
...@@ -275,11 +275,6 @@ def quote(file): ...@@ -275,11 +275,6 @@ def quote(file):
if not file: if not file:
return "''" return "''"
return file return file
if '\'' not in file: # use single quotes, and put single quotes into double quotes
return '\'' + file + '\'' # the string $'b is then quoted as '$'"'"'b'
res = '' return "'" + file.replace("'", "'\"'\"'") + "'"
for c in file:
if c in _funnychars:
c = '\\' + c
res = res + c
return '"' + res + '"'
...@@ -64,9 +64,10 @@ class SimplePipeTests(unittest.TestCase): ...@@ -64,9 +64,10 @@ class SimplePipeTests(unittest.TestCase):
self.assertEqual(open(TESTFN).read(), d) self.assertEqual(open(TESTFN).read(), d)
def testQuoting(self): def testQuoting(self):
safeunquoted = string.ascii_letters + string.digits + '!@%_-+=:,./' safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./'
unsafe = '"`$\\' unsafe = '"`$\\!'
self.assertEqual(pipes.quote(''), "''")
self.assertEqual(pipes.quote(safeunquoted), safeunquoted) self.assertEqual(pipes.quote(safeunquoted), safeunquoted)
self.assertEqual(pipes.quote('test file name'), "'test file name'") self.assertEqual(pipes.quote('test file name'), "'test file name'")
for u in unsafe: for u in unsafe:
...@@ -74,9 +75,7 @@ class SimplePipeTests(unittest.TestCase): ...@@ -74,9 +75,7 @@ class SimplePipeTests(unittest.TestCase):
"'test%sname'" % u) "'test%sname'" % u)
for u in unsafe: for u in unsafe:
self.assertEqual(pipes.quote("test%s'name'" % u), self.assertEqual(pipes.quote("test%s'name'" % u),
'"test\\%s\'name\'"' % u) "'test%s'\"'\"'name'\"'\"''" % u)
self.assertEqual(pipes.quote(''), "''")
def testRepr(self): def testRepr(self):
t = pipes.Template() t = pipes.Template()
......
...@@ -25,6 +25,8 @@ Core and Builtins ...@@ -25,6 +25,8 @@ Core and Builtins
Library Library
------- -------
- Issue #7507: Quote "!" in pipes.quote(); it is special to some shells.
- Issue #5238: Calling makefile() on an SSL object would prevent the - Issue #5238: Calling makefile() on an SSL object would prevent the
underlying socket from being closed until all objects get truely destroyed. underlying socket from being closed until all objects get truely destroyed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment