]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bug #18745 with invoking Windows batch files with embedded whitespace.
authorNoam Postavsky <npostavs@gmail.com>
Sat, 25 Oct 2014 09:12:01 +0000 (12:12 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 25 Oct 2014 09:12:01 +0000 (12:12 +0300)
 src/w32proc.c (create_child): If calling a quoted batch file,
 pass NULL for exe.

 nt/cmdproxy.c (batch_file_p): New function.
 (spawn): If calling a quoted batch file pass NULL for progname.

 test/automated/process-tests.el (process-test-quoted-batfile): New test.

nt/ChangeLog
nt/cmdproxy.c
src/ChangeLog
src/w32proc.c
test/ChangeLog
test/automated/process-tests.el

index 632c37394932ec80d1471fb1b4aecf955b1df658..c4e01a38c21b61a523189f1833cb1a8c93215ad2 100644 (file)
@@ -1,3 +1,9 @@
+2014-10-22  Noam Postavsky  <npostavs@users.sourceforget.net>
+
+       * nt/cmdproxy.c (batch_file_p): New function.
+       (spawn): If calling a quoted batch file pass NULL for progname.
+       (Bug#18745)
+
 2014-10-20  Glenn Morris  <rgm@gnu.org>
 
        * Merge in all changes up to 24.4 release.
index e48ca63a2579e29a783d471ca124370b3c6ffd74..d8f7ae3c41e9ebcaab5b2875980d010c07a9f331 100644 (file)
@@ -220,6 +220,28 @@ get_next_token (char * buf, const char ** pSrc)
   return o - buf;
 }
 
+/* Return TRUE if PROGNAME is a batch file. */
+BOOL
+batch_file_p (const char *progname)
+{
+  const char *exts[] = {".bat", ".cmd"};
+  int n_exts = sizeof (exts) / sizeof (char *);
+  int i;
+
+  const char *ext = strrchr (progname, '.');
+
+  if (ext)
+    {
+      for (i = 0; i < n_exts; i++)
+        {
+          if (stricmp (ext, exts[i]) == 0)
+            return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 /* Search for EXEC file in DIR.  If EXEC does not have an extension,
    DIR is searched for EXEC with the standard extensions appended.  */
 int
@@ -470,6 +492,13 @@ spawn (const char *progname, char *cmdline, const char *dir, int *retcode)
   memset (&start, 0, sizeof (start));
   start.cb = sizeof (start);
 
+  /* CreateProcess handles batch files as progname specially. This
+     special handling fails when both the batch file and arguments are
+     quoted.  We pass NULL as progname to avoid the special
+     handling. */
+  if (progname != NULL && cmdline[0] == '"' && batch_file_p (progname))
+      progname = NULL;
+
   if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE,
                     0, envblock, dir, &start, &child))
   {
index a1b70b63755ab4f4585e920c3db0f13882e07165..fb724fb583f763fbcb5e53da827a4ff1fdb9ef1e 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-25  Noam Postavsky  <npostavs@users.sourceforget.net>
+
+       * src/w32proc.c (create_child): If calling a quoted batch file,
+       pass NULL for exe.  (Bug#18745)
+
 2014-10-24  Eli Zaretskii  <eliz@gnu.org>
 
        * bidi.c (bidi_resolve_explicit, bidi_find_bracket_pairs)
index 38452917addb9a301d15dce1be2035afb6169b6c..09e0c0530a455b853b0fb50335c2787e6d4748f1 100644 (file)
@@ -1078,6 +1078,7 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
   DWORD flags;
   char dir[ MAX_PATH ];
   char *p;
+  const char *ext;
 
   if (cp == NULL) emacs_abort ();
 
@@ -1116,6 +1117,15 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
     if (*p == '/')
       *p = '\\';
 
+  /* CreateProcess handles batch files as exe specially.  This special
+     handling fails when both the batch file and arguments are quoted.
+     We pass NULL as exe to avoid the special handling. */
+  if (exe && cmdline[0] == '"' &&
+      (ext = strrchr (exe, '.')) &&
+      (xstrcasecmp (ext, ".bat") == 0
+       || xstrcasecmp (ext, ".cmd") == 0))
+      exe = NULL;
+
   flags = (!NILP (Vw32_start_process_share_console)
           ? CREATE_NEW_PROCESS_GROUP
           : CREATE_NEW_CONSOLE);
index bb4b2fbdc4953b3e877f971c93631496efb6d707..fb19252cd3452c49344212c03130974d11c175b9 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-22  Noam Postavsky  <npostavs@users.sourceforget.net>
+
+       * test/automated/process-tests.el (process-test-quoted-batfile):
+       New test.
+
 2014-10-20  Glenn Morris  <rgm@gnu.org>
 
        * Merge in all changes up to 24.4 release.
index cd209bacaa68aae741b37070bf737d412e1dbb45..6783a61d5954aa7cdf17a5a253f85c33024a5908 100644 (file)
   (should
    (process-test-sentinel-wait-function-working-p (lambda () (sit-for 0.01 t)))))
 
+(when (eq system-type 'windows-nt)
+  (ert-deftest process-test-quoted-batfile ()
+    "Check that Emacs hides CreateProcess deficiency (bug#18745)."
+    (let (batfile)
+      (unwind-protect
+          (progn
+            ;; CreateProcess will fail when both the bat file and 1st
+            ;; argument are quoted, so include spaces in both of those
+            ;; to force quoting.
+            (setq batfile (make-temp-file "echo args" nil ".bat"))
+            (with-temp-file batfile
+              (insert "@echo arg1 = %1, arg2 = %2\n"))
+            (with-temp-buffer
+              (call-process batfile nil '(t t) t "x &y")
+              (should (string= (buffer-string) "arg1 = \"x &y\", arg2 = \n")))
+            (with-temp-buffer
+              (call-process-shell-command
+               (mapconcat #'shell-quote-argument (list batfile "x &y") " ")
+               nil '(t t) t)
+              (should (string= (buffer-string) "arg1 = \"x &y\", arg2 = \n"))))
+        (when batfile (delete-file batfile))))))
+
 (provide 'process-tests)