aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2016-09-11 03:27:35 +0200
committerJustin M. Keyes <justinkz@gmail.com>2016-09-11 03:27:35 +0200
commitca65514a241b239e656cb87f0912bd9ba2e18ad8 (patch)
tree104596d8b46c823969085c4ebf8a39dd12982646 /src
parent8dc6c1a7ff97700a0622497245f2d5d257e1dfdb (diff)
parent395ef5642e6e61d8f59d1ef67dd7d203b9bb72e6 (diff)
downloadrneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.tar.gz
rneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.tar.bz2
rneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.zip
Merge #2789 'system(): Respect shellxescape, shellxquote'
Diffstat (limited to 'src')
-rw-r--r--src/nvim/misc2.c24
-rw-r--r--src/nvim/os/shell.c42
2 files changed, 40 insertions, 26 deletions
diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c
index 368f83cfb5..8b4d8c7c3e 100644
--- a/src/nvim/misc2.c
+++ b/src/nvim/misc2.c
@@ -281,7 +281,6 @@ int default_fileformat(void)
// Call shell. Calls os_call_shell, with 'shellxquote' added.
int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
{
- char_u *ncmd;
int retval;
proftime_T wait_time;
@@ -303,28 +302,7 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
/* The external command may update a tags file, clear cached tags. */
tag_freematch();
- if (cmd == NULL || *p_sxq == NUL)
- retval = os_call_shell(cmd, opts, extra_shell_arg);
- else {
- char_u *ecmd = cmd;
-
- if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
- ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
- }
- ncmd = xmalloc(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1);
- STRCPY(ncmd, p_sxq);
- STRCAT(ncmd, ecmd);
- /* When 'shellxquote' is ( append ).
- * When 'shellxquote' is "( append )". */
- STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")"
- : STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\""
- : p_sxq);
- retval = os_call_shell(ncmd, opts, extra_shell_arg);
- xfree(ncmd);
-
- if (ecmd != cmd)
- xfree(ecmd);
- }
+ retval = os_call_shell(cmd, opts, extra_shell_arg);
}
set_vim_var_nr(VV_SHELL_ERROR, (varnumber_T) retval);
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index ba52b9f661..99ae3af221 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -54,12 +54,12 @@ char **shell_build_argv(const char *cmd, const char *extra_args)
size_t i = tokenize(p_sh, rv);
if (extra_args) {
- rv[i++] = xstrdup(extra_args); // Push a copy of `extra_args`
+ rv[i++] = xstrdup(extra_args); // Push a copy of `extra_args`
}
if (cmd) {
- i += tokenize(p_shcf, rv + i); // Split 'shellcmdflag'
- rv[i++] = xstrdup(cmd); // Push a copy of the command.
+ i += tokenize(p_shcf, rv + i); // Split 'shellcmdflag'
+ rv[i++] = shell_xescape_xquote(cmd); // Copy (and escape) `cmd`.
}
rv[i] = NULL;
@@ -548,3 +548,39 @@ static void shell_write_cb(Stream *stream, void *data, int status)
{
stream_close(stream, NULL, NULL);
}
+
+/// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command.
+///
+/// @param cmd Command string
+/// @return Escaped/quoted command string (allocated).
+static char *shell_xescape_xquote(const char *cmd)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (*p_sxq == NUL) {
+ return xstrdup(cmd);
+ }
+
+ const char *ecmd = cmd;
+ if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
+ ecmd = (char *)vim_strsave_escaped_ext((char_u *)cmd, p_sxe, '^', false);
+ }
+ size_t ncmd_size = strlen(ecmd) + STRLEN(p_sxq) * 2 + 1;
+ char *ncmd = xmalloc(ncmd_size);
+
+ // When 'shellxquote' is ( append ).
+ // When 'shellxquote' is "( append )".
+ if (STRCMP(p_sxq, "(") == 0) {
+ vim_snprintf(ncmd, ncmd_size, "(%s)", ecmd);
+ } else if (STRCMP(p_sxq, "\"(") == 0) {
+ vim_snprintf(ncmd, ncmd_size, "\"(%s)\"", ecmd);
+ } else {
+ vim_snprintf(ncmd, ncmd_size, "%s%s%s", p_sxq, ecmd, p_sxq);
+ }
+
+ if (ecmd != cmd) {
+ xfree((void *)ecmd);
+ }
+
+ return ncmd;
+}
+