]> granicus.if.org Git - vim/commitdiff
patch 8.0.1176: job_start() does not handle quote and backslash correctly v8.0.1176
authorBram Moolenaar <Bram@vim.org>
Thu, 5 Oct 2017 23:07:41 +0000 (01:07 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 5 Oct 2017 23:07:41 +0000 (01:07 +0200)
Problem:    Job_start() does not handle quote and backslash correctly.
Solution:   Remove quotes, recognize and remove backslashes.

src/os_unix.c
src/testdir/test_channel.vim
src/version.c

index 2a8e6ee43b41727d92815672bfc5ae96b2404917..59e5745de74174794ee3a2a79ede7e08050a7961 100644 (file)
@@ -4074,7 +4074,7 @@ wait4pid(pid_t child, waitstatus *status)
 mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
 {
     int                i;
-    char_u     *p;
+    char_u     *p, *d;
     int                inquote;
 
     /*
@@ -4092,26 +4092,34 @@ mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
            if (i == 1)
                (*argv)[*argc] = (char *)p;
            ++*argc;
+           d = p;
            while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
            {
                if (p[0] == '"')
+                   /* quotes surrounding an argument and are dropped */
                    inquote = !inquote;
-               else if (p[0] == '\\' && p[1] != NUL)
+               else
                {
-                   /* First pass: skip over "\ " and "\"".
-                    * Second pass: Remove the backslash. */
-                   if (i == 1)
-                       mch_memmove(p, p + 1, STRLEN(p));
-                   else
+                   if (p[0] == '\\' && p[1] != NUL)
+                   {
+                       /* First pass: skip over "\ " and "\"".
+                        * Second pass: Remove the backslash. */
                        ++p;
+                   }
+                   if (i == 1)
+                       *d++ = *p;
                }
                ++p;
            }
            if (*p == NUL)
+           {
+               if (i == 1)
+                   *d++ = NUL;
                break;
+           }
            if (i == 1)
-               *p++ = NUL;
-           p = skipwhite(p);
+               *d++ = NUL;
+           p = skipwhite(p + 1);
        }
        if (*argv == NULL)
        {
index 951f9a3baf517bf57a36a0b257d37421fb67ffb4..9dba0c4b753257d5c07f244cf505be081c48e3a9 100644 (file)
@@ -1590,6 +1590,22 @@ func Test_collapse_buffers()
   bwipe!
 endfunc
 
+func Test_cmd_parsing()
+  if !has('unix')
+    return
+  endif
+  call assert_false(filereadable("file with space"))
+  let job = job_start('touch "file with space"')
+  call WaitFor('filereadable("file with space")')
+  call assert_true(filereadable("file with space"))
+  call delete("file with space")
+
+  let job = job_start('touch file\ with\ space')
+  call WaitFor('filereadable("file with space")')
+  call assert_true(filereadable("file with space"))
+  call delete("file with space")
+endfunc
+
 func Test_raw_passes_nul()
   if !executable('cat') || !has('job')
     return
index b31943fc0d4a7c618ad6425c96d8804d884382a6..8d7a5e5bd320931d77df9a4fa4993d152a717c32 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1176,
 /**/
     1175,
 /**/