Mercurial > vim
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