vim-patch:8.2.1219: symlink not followed if dirname ends in //

Problem:    Symlink not followed if dirname ends in //.
Solution:   Resolve symlink earlier. (Tomáš Janoušek, closes vim/vim#6454)
5966ea105e
This commit is contained in:
Jan Edmund Lazo
2020-10-16 23:02:13 -04:00
parent 1d736a1ae2
commit a2e1bcd176
3 changed files with 56 additions and 25 deletions

View File

@@ -3593,7 +3593,7 @@ restore_backup:
* the backup file our 'original' file. * the backup file our 'original' file.
*/ */
if (*p_pm && dobackup) { if (*p_pm && dobackup) {
char *org = modname((char *)fname, (char *)p_pm, FALSE); char *const org = modname((char *)fname, (char *)p_pm, false);
if (backup != NULL) { if (backup != NULL) {
/* /*

View File

@@ -1360,7 +1360,7 @@ recover_names (
* Try finding a swap file by simply adding ".swp" to the file name. * Try finding a swap file by simply adding ".swp" to the file name.
*/ */
if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) { if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) {
char_u *swapname = (char_u *)modname((char *)fname_res, ".swp", TRUE); char_u *swapname = (char_u *)modname((char *)fname_res, ".swp", true);
if (swapname != NULL) { if (swapname != NULL) {
if (os_path_exists(swapname)) { if (os_path_exists(swapname)) {
files = xmalloc(sizeof(char_u *)); files = xmalloc(sizeof(char_u *));
@@ -1638,10 +1638,11 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
// May also add the file name with a dot prepended, for swap file in same // May also add the file name with a dot prepended, for swap file in same
// dir as original file. // dir as original file.
if (prepend_dot) { if (prepend_dot) {
names[num_names] = (char_u *)modname((char *)path, ".sw?", TRUE); names[num_names] = (char_u *)modname((char *)path, ".sw?", true);
if (names[num_names] == NULL) if (names[num_names] == NULL) {
return num_names; return num_names;
++num_names; }
num_names++;
} }
// Form the normal swap file name pattern by appending ".sw?". // Form the normal swap file name pattern by appending ".sw?".
@@ -2422,17 +2423,17 @@ int ml_replace(linenr_T lnum, char_u *line, bool copy)
return ml_replace_buf(curbuf, lnum, line, copy); return ml_replace_buf(curbuf, lnum, line, copy);
} }
/* // Replace line "lnum", with buffering, in current buffer.
* Replace line lnum, with buffering, in current buffer. //
* // If "copy" is true, make a copy of the line, otherwise the line has been
* If "copy" is TRUE, make a copy of the line, otherwise the line has been // copied to allocated memory already.
* copied to allocated memory already. // If "copy" is false the "line" may be freed to add text properties!
* // Do not use it after calling ml_replace().
* Check: The caller of this function should probably also call //
* changed_lines(), unless update_screen(NOT_VALID) is used. // Check: The caller of this function should probably also call
* // changed_lines(), unless update_screen(NOT_VALID) is used.
* return FAIL for failure, OK otherwise //
*/ // return FAIL for failure, OK otherwise
int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy) int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy)
{ {
if (line == NULL) /* just checking... */ if (line == NULL) /* just checking... */
@@ -3193,6 +3194,12 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
char_u *fname_res = fname; char_u *fname_res = fname;
#ifdef HAVE_READLINK #ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL]; char_u fname_buf[MAXPATHL];
// Expand symlink in the file name, so that we put the swap file with the
// actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
}
#endif #endif
int len = (int)STRLEN(dir_name); int len = (int)STRLEN(dir_name);
@@ -3201,20 +3208,14 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
&& len > 1 && len > 1
&& s[-1] == s[-2]) { // Ends with '//', Use Full path && s[-1] == s[-2]) { // Ends with '//', Use Full path
r = NULL; r = NULL;
if ((s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname)) != NULL) { s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname_res);
r = (char_u *)modname((char *)s, ".swp", FALSE); if (s != NULL) {
r = (char_u *)modname((char *)s, ".swp", false);
xfree(s); xfree(s);
} }
return r; return r;
} }
#ifdef HAVE_READLINK
/* Expand symlink in the file name, so that we put the swap file with the
* actual file instead of with the symlink. */
if (resolve_symlink(fname, fname_buf) == OK)
fname_res = fname_buf;
#endif
// Prepend a '.' to the swap file name for the current directory. // Prepend a '.' to the swap file name for the current directory.
r = (char_u *)modname((char *)fname_res, ".swp", r = (char_u *)modname((char *)fname_res, ".swp",
dir_name[0] == '.' && dir_name[1] == NUL); dir_name[0] == '.' && dir_name[1] == NUL);

View File

@@ -334,4 +334,34 @@ func Test_swap_prompt_splitwin()
call delete('Xfile1') call delete('Xfile1')
endfunc endfunc
func Test_swap_symlink()
if !has("unix")
return
endif
call writefile(['text'], 'Xtestfile')
silent !ln -s -f Xtestfile Xtestlink
set dir=.
" Test that swap file uses the name of the file when editing through a
" symbolic link (so that editing the file twice is detected)
edit Xtestlink
call assert_match('Xtestfile\.swp$', s:swapname())
bwipe!
call mkdir('Xswapdir')
exe 'set dir=' . getcwd() . '/Xswapdir//'
" Check that this also works when 'directory' ends with '//'
edit Xtestlink
call assert_match('Xtestfile\.swp$', s:swapname())
bwipe!
set dir&
call delete('Xtestfile')
call delete('Xtestlink')
call delete('Xswapdir', 'rf')
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab