]> granicus.if.org Git - python/commitdiff
#7507: quote "!" in pipes.quote(); it is a special character for some shells.
authorGeorg Brandl <georg@python.org>
Sat, 24 Apr 2010 09:08:10 +0000 (09:08 +0000)
committerGeorg Brandl <georg@python.org>
Sat, 24 Apr 2010 09:08:10 +0000 (09:08 +0000)
Lib/pipes.py
Lib/test/test_pipes.py
Misc/NEWS

index 25e99159b8a1e86a8ceeab9001d70acbd4b1649a..02e125743b8dc4f8e1e4dae1392edf448922a5b9 100644 (file)
@@ -263,11 +263,11 @@ def makepipeline(infile, steps, outfile):
 
 # Reliably quote a string as a single argument for /bin/sh
 
-_safechars = string.ascii_letters + string.digits + '!@%_-+=:,./' # Safe unquoted
-_funnychars = '"`$\\'                           # Unsafe inside "double quotes"
+# Safe unquoted
+_safechars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./')
 
 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:
         if c not in _safechars:
             break
@@ -275,11 +275,6 @@ def quote(file):
         if not file:
             return "''"
         return file
-    if '\'' not in file:
-        return '\'' + file + '\''
-    res = ''
-    for c in file:
-        if c in _funnychars:
-            c = '\\' + c
-        res = res + c
-    return '"' + res + '"'
+    # use single quotes, and put single quotes into double quotes
+    # the string $'b is then quoted as '$'"'"'b'
+    return "'" + file.replace("'", "'\"'\"'") + "'"
index a6385984031e8779f8c2981e0f897b0e04dbcd63..476bd7c6440a9cedc14e322a52ed1bfc79fc8cb4 100644 (file)
@@ -64,9 +64,10 @@ class SimplePipeTests(unittest.TestCase):
         self.assertEqual(open(TESTFN).read(), d)
 
     def testQuoting(self):
-        safeunquoted = string.ascii_letters + string.digits + '!@%_-+=:,./'
-        unsafe = '"`$\\'
+        safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./'
+        unsafe = '"`$\\!'
 
+        self.assertEqual(pipes.quote(''), "''")
         self.assertEqual(pipes.quote(safeunquoted), safeunquoted)
         self.assertEqual(pipes.quote('test file name'), "'test file name'")
         for u in unsafe:
@@ -74,9 +75,7 @@ class SimplePipeTests(unittest.TestCase):
                               "'test%sname'" % u)
         for u in unsafe:
             self.assertEqual(pipes.quote("test%s'name'" % u),
-                              '"test\\%s\'name\'"' % u)
-
-        self.assertEqual(pipes.quote(''), "''")
+                             "'test%s'\"'\"'name'\"'\"''" % u)
 
     def testRepr(self):
         t = pipes.Template()
index 580f9bf85d249d535969c5dd0609bd5020d8ce55..747c0c2a307a357ecc877a1b5d684cc68c10b8c0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -25,6 +25,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #7507: Quote "!" in pipes.quote(); it is special to some shells.
+
 - Issue #5238: Calling makefile() on an SSL object would prevent the
   underlying socket from being closed until all objects get truely destroyed.