]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Avoid unwanted behavior change in shlex.quote (see #9723).
authorÉric Araujo <merwok@netwok.org>
Tue, 9 Aug 2011 21:18:06 +0000 (23:18 +0200)
committerÉric Araujo <merwok@netwok.org>
Tue, 9 Aug 2011 21:18:06 +0000 (23:18 +0200)
I simplified the quote code to use a regex instead of a loop+test when I
moved pipes.quote to shlex in 5966eeb0457d; Ezio Melotti pointed out
that my regex contained redundant parts (now removed) and allowed
non-ASCII characters (now disallowed).

I think common UNIX shells don’t quote non-ASCII characters, but there’s
no harm in doing so.  We’ll see if users request a change.

1  2 
Lib/shlex.py
Lib/test/test_shlex.py

diff --cc Lib/shlex.py
index 279ab484059514c145917d746f3cb3d52a767599,3edd3db1ed9ed445cba637570e6a04a2652765b3..92c49c360842db6250cf7854bf07ca8aa7f47dfa
@@@ -275,21 -274,6 +275,21 @@@ def split(s, comments=False, posix=True
          lex.commenters = ''
      return list(lex)
  
- _find_unsafe = re.compile(r'[^\w\d@%_\-\+=:,\./]').search
 +
++_find_unsafe = re.compile(r'[^\w@%\-\+=:,\./]', re.ASCII).search
 +
 +def quote(s):
 +    """Return a shell-escaped version of the string *s*."""
 +    if not s:
 +        return "''"
 +    if _find_unsafe(s) is None:
 +        return s
 +
 +    # use single quotes, and put single quotes into double quotes
 +    # the string $'b is then quoted as '$'"'"'b'
 +    return "'" + s.replace("'", "'\"'\"'") + "'"
 +
 +
  if __name__ == '__main__':
      if len(sys.argv) == 1:
          lexer = shlex()
index ea3d777ceba37ff7b7c36b8744df4fc851c96272,25e4b6df6c5d2403c5d2f7b3431ffa03da663541..d4463f300481c40766e1921799dd8cb9731367af
@@@ -174,21 -173,6 +174,22 @@@ class ShlexTest(unittest.TestCase)
                               "%s: %s != %s" %
                               (self.data[i][0], l, self.data[i][1:]))
  
-         unsafe = '"`$\\!'
 +    def testQuote(self):
 +        safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./'
++        unicode_sample = '\xe9\xe0\xdf'  # e + acute accent, a + grave, sharp s
++        unsafe = '"`$\\!' + unicode_sample
 +
 +        self.assertEqual(shlex.quote(''), "''")
 +        self.assertEqual(shlex.quote(safeunquoted), safeunquoted)
 +        self.assertEqual(shlex.quote('test file name'), "'test file name'")
 +        for u in unsafe:
 +            self.assertEqual(shlex.quote('test%sname' % u),
 +                             "'test%sname'" % u)
 +        for u in unsafe:
 +            self.assertEqual(shlex.quote("test%s'name'" % u),
 +                             "'test%s'\"'\"'name'\"'\"''" % u)
 +
 +
  # Allow this test to be used with old shlex.py
  if not getattr(shlex, "split", None):
      for methname in dir(ShlexTest):