vim-patch:8.0.0444: diffpatch fails when the file name has a quote

Problem:    Diffpatch fails when the file name has a quote.
Solution:   Escape the name properly. (zetzei)

a95ab32120
This commit is contained in:
Justin M. Keyes 2018-01-21 10:36:14 +01:00
parent 456cf72974
commit ab279c6fb8
2 changed files with 25 additions and 28 deletions

View File

@ -856,11 +856,12 @@ void ex_diffpatch(exarg_T *eap)
char_u *buf = NULL;
win_T *old_curwin = curwin;
char_u *newname = NULL; // name of patched file buffer
char_u *esc_name = NULL;
#ifdef UNIX
char_u dirbuf[MAXPATHL];
char_u *fullname = NULL;
#endif // ifdef UNIX
#endif
// We need two temp file names.
// Name of original temp file.
char_u *tmp_orig = vim_tempname();
@ -880,21 +881,21 @@ void ex_diffpatch(exarg_T *eap)
#ifdef UNIX
// Get the absolute path of the patchfile, changing directory below.
fullname = (char_u *)FullName_save((char *)eap->arg, FALSE);
#endif // ifdef UNIX
fullname = (char_u *)FullName_save((char *)eap->arg, false);
#endif
esc_name = vim_strsave_shellescape(
#ifdef UNIX
size_t buflen = STRLEN(tmp_orig)
+ (fullname != NULL ? STRLEN(fullname) : STRLEN(eap->arg))
+ STRLEN(tmp_new) + 16;
#else
size_t buflen = STRLEN(tmp_orig) + (STRLEN(eap->arg)) + STRLEN(tmp_new) + 16;
#endif // ifdef UNIX
fullname != NULL ? fullname :
#endif
eap->arg, true, true);
if (esc_name == NULL) {
goto theend;
}
size_t buflen = STRLEN(tmp_orig) + STRLEN(esc_name) + STRLEN(tmp_new) + 16;
buf = xmalloc(buflen);
#ifdef UNIX
// Temporarily chdir to /tmp, to avoid patching files in the current
// directory when the patch file contains more than one patch. When we
// have our own temp dir use that instead, it will be cleaned up when we
@ -911,26 +912,21 @@ void ex_diffpatch(exarg_T *eap)
os_chdir(tempdir);
shorten_fnames(TRUE);
}
#endif // ifdef UNIX
#endif
if (*p_pex != NUL) {
// Use 'patchexpr' to generate the new file.
#ifdef UNIX
eval_patch((char *) tmp_orig,
(char *) (fullname != NULL ? fullname : eap->arg),
(char *) tmp_new);
eval_patch((char *)tmp_orig,
(char *)(fullname != NULL ? fullname : eap->arg),
(char *)tmp_new);
#else
eval_patch((char *) tmp_orig, (char *) eap->arg, (char *) tmp_new);
#endif // ifdef UNIX
eval_patch((char *)tmp_orig, (char *)eap->arg, (char *)tmp_new);
#endif
} else {
// Build the patch command and execute it. Ignore errors.
#ifdef UNIX
vim_snprintf((char *)buf, buflen, "patch -o %s %s < '%s'",
tmp_new, tmp_orig, fullname != NULL ? fullname : eap->arg);
#else
vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
tmp_new, tmp_orig, eap->arg);
#endif // ifdef UNIX
vim_snprintf((char *)buf, buflen, "patch -o %s %s < %s",
tmp_new, tmp_orig, esc_name);
block_autocmds(); // Avoid ShellCmdPost stuff
(void)call_shell(buf, kShellOptFilter, NULL);
unblock_autocmds();
@ -943,7 +939,7 @@ void ex_diffpatch(exarg_T *eap)
}
shorten_fnames(TRUE);
}
#endif // ifdef UNIX
#endif
// patch probably has written over the screen
redraw_later(CLEAR);
@ -1012,7 +1008,8 @@ theend:
xfree(buf);
#ifdef UNIX
xfree(fullname);
#endif // ifdef UNIX
#endif
xfree(esc_name);
}
/// Split the window and edit another file, setting options to show the diffs.
@ -1163,7 +1160,7 @@ void ex_diffoff(exarg_T *eap)
free_string_option(wp->w_p_fdm);
wp->w_p_fdm = vim_strsave(*wp->w_p_fdm_save
? wp->w_p_fdm_save
: (char_u*)"manual");
: (char_u *)"manual");
if (wp->w_p_fdc == diff_foldcolumn) {
wp->w_p_fdc = wp->w_p_fdc_save;
}

View File

@ -502,7 +502,7 @@ func Test_diffpatch()
new
call assert_fails('diffpatch Xpatch', 'E816:')
for name in ['Xpatch', 'Xpatch$HOME']
for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
call setline(1, ['1', '2', '3'])
if name != 'Xpatch'
call rename('Xpatch', name)