Bug 780612 - Add a list of characters which probably indicate shell scripts but native commands won't reject. r=khuey
authorSiddharth Agarwal <sid.bugzilla@gmail.com>
Wed, 08 Aug 2012 00:48:46 +0530
changeset 320 7d221562bc4a
parent 319 368af0ee4aa9
child 321 8360595070d6
push id196
push usersid.bugzilla@gmail.com
push dateTue, 07 Aug 2012 19:27:20 +0000
reviewerskhuey
bugs780612
Bug 780612 - Add a list of characters which probably indicate shell scripts but native commands won't reject. r=khuey
pymake/data.py
pymake/process.py
tests/native-simple.mk
--- a/pymake/data.py
+++ b/pymake/data.py
@@ -1381,17 +1381,17 @@ class _CommandWrapper(object):
         process.call(self.cline, loc=self.loc, cb=self._cb, context=self.context, **self.kwargs)
 
 class _NativeWrapper(_CommandWrapper):
     def __init__(self, cline, ignoreErrors, loc, context,
                  pycommandpath, **kwargs):
         _CommandWrapper.__init__(self, cline, ignoreErrors, loc, context,
                                  **kwargs)
         # get the module and method to call
-        parts, badchar = process.clinetoargv(cline)
+        parts, badchar = process.clinetoargv(cline, blacklist_gray=False)
         if parts is None:
             raise DataError("native command '%s': shell metacharacter '%s' in command line" % (cline, badchar), self.loc)
         if len(parts) < 2:
             raise DataError("native command '%s': no method name specified" % cline, self.loc)
         if pycommandpath:
             self.pycommandpath = re.split('[%s\s]+' % os.pathsep,
                                           pycommandpath)
         else:
--- a/pymake/process.py
+++ b/pymake/process.py
@@ -10,29 +10,39 @@ import subprocess, shlex, re, logging, s
 subprocess._cleanup = lambda: None
 import command, util
 if sys.platform=='win32':
     import win32process
 
 _log = logging.getLogger('pymake.process')
 
 _escapednewlines = re.compile(r'\\\n')
-_blacklist = re.compile(r'[$><;[~`|&()]' +
+# Characters that most likely indicate a shell script and that native commands
+# should reject
+_blacklist = re.compile(r'[$><;\[~`|&]' +
     r'|\${|(?:^|\s){(?:$|\s)')  # Blacklist ${foo} and { commands }
+# Characters that probably indicate a shell script, but that native commands
+# shouldn't just reject
+_graylist = re.compile(r'[()]')
+# Characters that indicate we need to glob
 _needsglob = re.compile(r'[\*\?]')
-def clinetoargv(cline):
+
+def clinetoargv(cline, blacklist_gray):
     """
     If this command line can safely skip the shell, return an argv array.
     @returns argv, badchar
     """
-
     str = _escapednewlines.sub('', cline)
     m = _blacklist.search(str)
     if m is not None:
         return None, m.group(0)
+    if blacklist_gray:
+        m = _graylist.search(str)
+        if m is not None:
+            return None, m.group(0)
 
     args = shlex.split(str, comments=True)
 
     if len(args) and args[0].find('=') != -1:
         return None, '='
 
     return args, None
 
@@ -60,17 +70,17 @@ shellwords = (':', '.', 'break', 'cd', '
 def call(cline, env, cwd, loc, cb, context, echo, justprint=False):
     #TODO: call this once up-front somewhere and save the result?
     shell, msys = util.checkmsyscompat()
 
     shellreason = None
     if msys and cline.startswith('/'):
         shellreason = "command starts with /"
     else:
-        argv, badchar = clinetoargv(cline)
+        argv, badchar = clinetoargv(cline, blacklist_gray=True)
         if argv is None:
             shellreason = "command contains shell-special character '%s'" % (badchar,)
         elif len(argv) and argv[0] in shellwords:
             shellreason = "command starts with shell primitive '%s'" % (argv[0],)
         else:
             argv = doglobbing(argv, cwd)
 
     if shellreason is not None:
--- a/tests/native-simple.mk
+++ b/tests/native-simple.mk
@@ -1,11 +1,12 @@
 ifndef TOUCH
 TOUCH = touch
 endif
 
-all: testfile {testfile2}
+all: testfile {testfile2} (testfile3)
 	test -f testfile
 	test -f {testfile2}
+	test -f "(testfile3)"
 	@echo TEST-PASS
 
-testfile {testfile2}:
-	$(TOUCH) $@
+testfile {testfile2} (testfile3):
+	$(TOUCH) "$@"