From 5db4a3a2a59ac730239de8dfb0c09afc89942fe7 Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Fri, 2 Mar 2018 12:44:49 +0000 Subject: [PATCH] Make robust the replacement of temp file paths with actual paths. The previous implementation meant the temp file paths were treated as regular expressions, which was vulnerable to problems with backslashes etc. See #494. --- autoload/gitgutter/hunk.vim | 25 +++++++++++--- test/test | 2 ++ test/test_gitgutter.vim | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim index dcc0cb7..5876d2b 100644 --- a/autoload/gitgutter/hunk.vim +++ b/autoload/gitgutter/hunk.vim @@ -228,13 +228,28 @@ endfunction " Replaces references to temp files with the actual file. function! s:fix_file_references(filepath, hunk_diff) - let diff = a:hunk_diff - for tmp in matchlist(diff, '\vdiff --git ./(\S+) ./(\S+)\n')[1:2] - let diff = substitute(diff, tmp, a:filepath, 'g') - endfor - return diff + let lines = split(a:hunk_diff, '\n') + + let left_prefix = matchstr(lines[2], '[abciow12]').'/' + let right_prefix = matchstr(lines[3], '[abciow12]').'/' + let quote = lines[0][11] == '"' ? '"' : '' + + let left_file = quote.left_prefix.a:filepath.quote + let right_file = quote.right_prefix.a:filepath.quote + + let lines[0] = 'diff --git '.left_file.' '.right_file + let lines[2] = '--- '.left_file + let lines[3] = '+++ '.right_file + + return join(lines, "\n")."\n" endfunction +if $TEST + function! gitgutter#hunk#fix_file_references(filepath, hunk_diff) + return s:fix_file_references(a:filepath, a:hunk_diff) + endfunction +endif + function! s:adjust_hunk_summary(hunk_diff) abort let line_adjustment = s:line_adjustment_for_current_hunk() diff --git a/test/test b/test/test index 6247a05..1ca0786 100755 --- a/test/test +++ b/test/test @@ -2,6 +2,8 @@ VIM="/Applications/MacVim.app/Contents/MacOS/Vim -v" +export TEST=1 + $VIM -u NONE -U NONE -N \ --cmd 'set rtp+=../' \ --cmd 'let g:gitgutter_async=0' \ diff --git a/test/test_gitgutter.vim b/test/test_gitgutter.vim index c15d569..c583576 100644 --- a/test/test_gitgutter.vim +++ b/test/test_gitgutter.vim @@ -494,3 +494,72 @@ function Test_user_autocmd() call s:trigger_gitgutter() call assert_equal(bufnr, s:autocmd_user) endfunction + + +function Test_fix_file_references() + " No special characters + let hunk_diff = join([ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + let filepath = 'blah.txt' + + let expected = join([ + \ 'diff --git a/blah.txt b/blah.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- a/blah.txt', + \ '+++ b/blah.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) + + " diff.mnemonicPrefix; spaces in filename + let hunk_diff = join([ + \ 'diff --git i/x/cat dog w/x/cat dog', + \ 'index f5c6aff..3fbde56 100644', + \ '--- i/x/cat dog', + \ '+++ w/x/cat dog', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + let filepath = 'blah.txt' + + let expected = join([ + \ 'diff --git i/blah.txt w/blah.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- i/blah.txt', + \ '+++ w/blah.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) + + " Backslashes in filename; quotation marks + let hunk_diff = join([ + \ 'diff --git "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim" "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"', + \ 'index f42aeb0..4930403 100644', + \ '--- "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim"', + \ '+++ "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"', + \ '@@ -172,0 +173 @@ stuff', + \ '+x' + \ ], "\n")."\n" + let filepath = 'init.vim' + + let expected = join([ + \ 'diff --git "a/init.vim" "b/init.vim"', + \ 'index f42aeb0..4930403 100644', + \ '--- "a/init.vim"', + \ '+++ "b/init.vim"', + \ '@@ -172,0 +173 @@ stuff', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) +endfunction