changeset 12596:d177c142d086 v8.0.1176

patch 8.0.1176: job_start() does not handle quote and backslash correctly commit https://github.com/vim/vim/commit/d78f03f86045184dfd191f00359baa61e2e79d1f Author: Bram Moolenaar <Bram@vim.org> Date: Fri Oct 6 01:07:41 2017 +0200 patch 8.0.1176: job_start() does not handle quote and backslash correctly Problem: Job_start() does not handle quote and backslash correctly. Solution: Remove quotes, recognize and remove backslashes.
author Christian Brabandt <cb@256bit.org>
date Fri, 06 Oct 2017 01:15:05 +0200
parents c1aacd5412cd
children e77b617333ea
files src/os_unix.c src/testdir/test_channel.vim src/version.c
diffstat 3 files changed, 35 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -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,
 	    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 (p[0] == '\\' && p[1] != NUL)
+		    {
+			/* First pass: skip over "\ " and "\"".
+			 * Second pass: Remove the backslash. */
+			++p;
+		    }
 		    if (i == 1)
-			mch_memmove(p, p + 1, STRLEN(p));
-		    else
-			++p;
+			*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)
 	{
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -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
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1176,
+/**/
     1175,
 /**/
     1174,