From: Bram Moolenaar Date: Thu, 5 Oct 2017 23:07:41 +0000 (+0200) Subject: patch 8.0.1176: job_start() does not handle quote and backslash correctly X-Git-Tag: v8.0.1176 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d78f03f86045184dfd191f00359baa61e2e79d1f;p=vim 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. --- diff --git a/src/os_unix.c b/src/os_unix.c index 2a8e6ee43..59e5745de 100644 --- 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, 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) { diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 951f9a3ba..9dba0c4b7 100644 --- 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 diff --git a/src/version.c b/src/version.c index b31943fc0..8d7a5e5bd 100644 --- a/src/version.c +++ b/src/version.c @@ -761,6 +761,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1176, /**/ 1175, /**/