# HG changeset patch # User Christian Brabandt # Date 1507245305 -7200 # Node ID d177c142d086339218fa74cb715302f9492e3a0c # Parent c1aacd5412cde9c538aca536f5d3f0f5c96a26c7 patch 8.0.1176: job_start() does not handle quote and backslash correctly commit https://github.com/vim/vim/commit/d78f03f86045184dfd191f00359baa61e2e79d1f Author: Bram Moolenaar 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. diff --git a/src/os_unix.c b/src/os_unix.c --- 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) { diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- 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 --- 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,