Encapsulate shell escaping user arguments

This commit is contained in:
Tim Pope 2019-08-15 21:31:53 -04:00
parent c972b2a065
commit 4f51d99f44

View File

@ -247,7 +247,7 @@ function! s:UserCommandList(...) abort
endfunction endfunction
function! s:UserCommand(...) abort function! s:UserCommand(...) abort
return s:shellesc(call('s:UserCommandList', a:000)) return s:shellesc(call('s:UserCommandList', a:0 ? [a:1] : []) + (a:0 ? a:2 : []))
endfunction endfunction
let s:git_versions = {} let s:git_versions = {}
@ -2126,27 +2126,26 @@ function! s:GitCommand(line1, line2, range, count, bang, mods, reg, arg, args) a
\ (args[0] ==# 'help' || get(args, 1, '') ==# '--help') && !s:HasOpt(args, '--web') \ (args[0] ==# 'help' || get(args, 1, '') ==# '--help') && !s:HasOpt(args, '--web')
return s:OpenExec((a:count > 0 ? a:count : '') . (a:count ? 'split' : 'edit'), a:mods, args, dir) . after return s:OpenExec((a:count > 0 ? a:count : '') . (a:count ? 'split' : 'edit'), a:mods, args, dir) . after
endif endif
let git = s:UserCommandList(dir)
if s:HasOpt(args, ['add', 'checkout', 'commit', 'stage', 'stash', 'reset'], '-p', '--patch') || if s:HasOpt(args, ['add', 'checkout', 'commit', 'stage', 'stash', 'reset'], '-p', '--patch') ||
\ s:HasOpt(args, ['add', 'clean', 'stage'], '-i', '--interactive') || \ s:HasOpt(args, ['add', 'clean', 'stage'], '-i', '--interactive') ||
\ index(['--paginate', '-p'], args[0]) >= 0 \ index(['--paginate', '-p'], args[0]) >= 0
let mods = substitute(s:Mods(a:mods), '\<tab\>', '-tab', 'g') let mods = substitute(s:Mods(a:mods), '\<tab\>', '-tab', 'g')
if has('nvim') if has('nvim')
if &autowrite || &autowriteall | silent! wall | endif if &autowrite || &autowriteall | silent! wall | endif
return mods . (a:count ? 'split' : 'edit') . ' term://' . s:fnameescape(s:shellesc(git + args)) . '|startinsert' . after return mods . (a:count ? 'split' : 'edit') . ' term://' . s:fnameescape(s:UserCommand(dir, args)) . '|startinsert' . after
elseif has('terminal') elseif has('terminal')
if &autowrite || &autowriteall | silent! wall | endif if &autowrite || &autowriteall | silent! wall | endif
return 'exe ' . string(mods . 'terminal ' . (a:count ? '' : '++curwin ') . join(map(git + args, 's:fnameescape(v:val)'))) . after return 'exe ' . string(mods . 'terminal ' . (a:count ? '' : '++curwin ') . join(map(s:UserCommandList(dir) + args, 's:fnameescape(v:val)'))) . after
endif endif
endif endif
if has('gui_running') && !has('win32') if has('gui_running') && !has('win32')
call add(git, '--no-pager') call insert(args, '--no-pager')
endif endif
let pre = '' let pre = ''
if has('nvim') && executable('env') if has('nvim') && executable('env')
let pre .= 'env GIT_TERMINAL_PROMPT=0 ' let pre .= 'env GIT_TERMINAL_PROMPT=0 '
endif endif
return 'exe ' . string('!' . escape(pre . s:shellesc(git + args), '!#%')) . after return 'exe ' . string('!' . escape(pre . s:UserCommand(dir, args), '!#%')) . after
endfunction endfunction
let s:exec_paths = {} let s:exec_paths = {}
@ -3252,7 +3251,7 @@ function! s:CommitSubcommand(line1, line2, range, bang, mods, args, ...) abort
let i += 1 let i += 1
endif endif
endwhile endwhile
let command .= s:UserCommand(dir) . ' commit ' . s:shellesc(argv) let command .= s:UserCommand(dir, ['commit'] + argv)
if (&autowrite || &autowriteall) && !a:0 if (&autowrite || &autowriteall) && !a:0
silent! wall silent! wall
endif endif
@ -3326,7 +3325,7 @@ endfunction
function! s:RevertSubcommand(line1, line2, range, bang, mods, args) abort function! s:RevertSubcommand(line1, line2, range, bang, mods, args) abort
let dir = s:Dir() let dir = s:Dir()
let no_commit = s:HasOpt(a:args, '-n', '--no-commit', '--no-edit', '--abort', '--continue', '--quit') let no_commit = s:HasOpt(a:args, '-n', '--no-commit', '--no-edit', '--abort', '--continue', '--quit')
let cmd = s:UserCommand(dir) . ' revert ' . (no_commit ? '' : '-n ') . s:shellesc(a:args) let cmd = s:UserCommand(dir, ['revert'] + (no_commit ? [] : ['-n']) + a:args)
let [out, exec_error] = s:SystemError(cmd) let [out, exec_error] = s:SystemError(cmd)
call fugitive#ReloadStatus(-1, 1) call fugitive#ReloadStatus(-1, 1)
if no_commit || exec_error if no_commit || exec_error
@ -3490,7 +3489,7 @@ function! s:MergeRebase(cmd, bang, mods, args, ...) abort
endif endif
endif endif
let had_merge_msg = filereadable(fugitive#Find('.git/MERGE_MSG', dir)) let had_merge_msg = filereadable(fugitive#Find('.git/MERGE_MSG', dir))
let argv = s:UserCommandList(dir) let argv = []
if a:cmd ==# 'pull' if a:cmd ==# 'pull'
let argv += s:AskPassArgs(dir) + ['pull', '--progress'] let argv += s:AskPassArgs(dir) + ['pull', '--progress']
else else
@ -3533,7 +3532,7 @@ function! s:MergeRebase(cmd, bang, mods, args, ...) abort
\ !empty(s:TreeChomp(dir, 'diff-files', '--diff-filter=U'))) \ !empty(s:TreeChomp(dir, 'diff-files', '--diff-filter=U')))
let cmd = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U' let cmd = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
else else
let cmd = s:shellesc(argv) let cmd = s:UserCommand(dir, argv)
endif endif
if !empty($GIT_SEQUENCE_EDITOR) || has('win32') if !empty($GIT_SEQUENCE_EDITOR) || has('win32')
let old_sequence_editor = $GIT_SEQUENCE_EDITOR let old_sequence_editor = $GIT_SEQUENCE_EDITOR
@ -3703,7 +3702,7 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, args) abort
let dir = s:Dir() let dir = s:Dir()
exe s:DirCheck(dir) exe s:DirCheck(dir)
let listnr = a:line1 == 0 ? a:line1 : a:line2 let listnr = a:line1 == 0 ? a:line1 : a:line2
let cmd = s:UserCommandList(dir) + ['--no-pager', 'grep', '-n', '--no-color', '--full-name'] let cmd = ['--no-pager', 'grep', '-n', '--no-color', '--full-name']
if fugitive#GitVersion(2, 19) if fugitive#GitVersion(2, 19)
call add(cmd, '--column') call add(cmd, '--column')
endif endif
@ -3725,7 +3724,7 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, args) abort
call s:QuickfixCreate(listnr, {'title': (listnr < 0 ? ':Ggrep ' : ':Glgrep ') . s:fnameescape(args)}) call s:QuickfixCreate(listnr, {'title': (listnr < 0 ? ':Ggrep ' : ':Glgrep ') . s:fnameescape(args)})
let tempfile = tempname() let tempfile = tempname()
if v:version > 704 | exe 'silent doautocmd <nomodeline> QuickFixCmdPre ' (listnr < 0 ? 'Ggrep' : 'Glgrep') | endif if v:version > 704 | exe 'silent doautocmd <nomodeline> QuickFixCmdPre ' (listnr < 0 ? 'Ggrep' : 'Glgrep') | endif
exe '!' . escape(s:shellesc(cmd + args), '%#!') exe '!' . escape(s:UserCommand(dir, cmd + args), '%#!')
\ printf(&shellpipe . (&shellpipe =~# '%s' ? '' : ' %s'), s:shellesc(tempfile)) \ printf(&shellpipe . (&shellpipe =~# '%s' ? '' : ' %s'), s:shellesc(tempfile))
let list = map(readfile(tempfile), 's:GrepParseLine(prefix, name_only, dir, v:val)') let list = map(readfile(tempfile), 's:GrepParseLine(prefix, name_only, dir, v:val)')
call s:QuickfixSet(listnr, list, 'a') call s:QuickfixSet(listnr, list, 'a')
@ -3844,7 +3843,7 @@ function! s:Log(type, bang, line1, count, args, legacy) abort
else else
let format = "%h\t%H " . g:fugitive_summary_format let format = "%h\t%H " . g:fugitive_summary_format
endif endif
let cmd = s:UserCommandList(dir) + ['--no-pager'] let cmd = ['--no-pager']
if fugitive#GitVersion(1, 9) if fugitive#GitVersion(1, 9)
call extend(cmd, ['-c', 'diff.context=0', 'log']) call extend(cmd, ['-c', 'diff.context=0', 'log'])
else else
@ -3858,7 +3857,7 @@ function! s:Log(type, bang, line1, count, args, legacy) abort
if empty(paths + extra) && a:legacy && len(s:Relative('/')) if empty(paths + extra) && a:legacy && len(s:Relative('/'))
let after = '|echohl WarningMsg|echo ' . string('Use :0Glog or :0Gclog for old behavior of targeting current file') . '|echohl NONE' . after let after = '|echohl WarningMsg|echo ' . string('Use :0Glog or :0Gclog for old behavior of targeting current file') . '|echohl NONE' . after
endif endif
return s:QuickfixStream(listnr, title, cmd, !a:bang, s:function('s:LogParse'), state, path, dir) . after return s:QuickfixStream(listnr, title, s:UserCommand(dir, cmd), !a:bang, s:function('s:LogParse'), state, path, dir) . after
endfunction endfunction
call s:command("-bang -nargs=? -range=-1 -addr=windows -complete=customlist,s:GrepComplete Ggrep", "grep") call s:command("-bang -nargs=? -range=-1 -addr=windows -complete=customlist,s:GrepComplete Ggrep", "grep")
@ -3925,9 +3924,7 @@ endfunction
function! s:OpenExec(cmd, mods, args, ...) abort function! s:OpenExec(cmd, mods, args, ...) abort
let dir = a:0 ? s:Dir(a:1) : s:Dir() let dir = a:0 ? s:Dir(a:1) : s:Dir()
let args = s:shellesc(a:args)
let temp = tempname() let temp = tempname()
let git = s:UserCommand(dir)
let columns = get(g:, 'fugitive_columns', 80) let columns = get(g:, 'fugitive_columns', 80)
if columns <= 0 if columns <= 0
let env = '' let env = ''
@ -3936,7 +3933,7 @@ function! s:OpenExec(cmd, mods, args, ...) abort
else else
let env = 'env COLUMNS=' . columns . ' ' let env = 'env COLUMNS=' . columns . ' '
endif endif
silent! execute '!' . escape(env . git . ' --no-pager ' . args, '!#%') . silent! execute '!' . escape(env . s:UserCommand(dir, ['--no-pager'] + a:args), '!#%') .
\ (&shell =~# 'csh' ? ' >& ' . temp : ' > ' . temp . ' 2>&1') \ (&shell =~# 'csh' ? ' >& ' . temp : ' > ' . temp . ' 2>&1')
redraw! redraw!
let temp = s:Resolve(temp) let temp = s:Resolve(temp)
@ -3952,7 +3949,7 @@ function! s:OpenExec(cmd, mods, args, ...) abort
endif endif
silent execute s:Mods(a:mods) . a:cmd temp silent execute s:Mods(a:mods) . a:cmd temp
call fugitive#ReloadStatus(dir, 1) call fugitive#ReloadStatus(dir, 1)
return 'echo ' . string(':!' . git . ' ' . args) return 'echo ' . string(':!' . s:UserCommand(dir, a:args))
endfunction endfunction
function! s:Open(cmd, bang, mods, arg, args) abort function! s:Open(cmd, bang, mods, arg, args) abort
@ -3990,12 +3987,11 @@ function! s:ReadCommand(line1, line2, range, count, bang, mods, reg, arg, args)
endif endif
if a:bang if a:bang
let dir = s:Dir() let dir = s:Dir()
let git = s:UserCommand(dir) let args = s:SplitExpand(a:arg, s:Tree(dir))
let args = s:shellesc(s:SplitExpand(a:arg, s:Tree(dir))) silent execute mods . after . 'read!' escape(s:UserCommand(dir, ['--no-pager'] + args), '!#%')
silent execute mods . after . 'read!' escape(git . ' --no-pager ' . args, '!#%')
execute delete . 'diffupdate' execute delete . 'diffupdate'
call fugitive#ReloadStatus() call fugitive#ReloadStatus()
return 'redraw|echo '.string(':!'.git.' '.args) return 'redraw|echo '.string(':!'.s:UserCommand(dir, args))
endif endif
exe s:DirCheck() exe s:DirCheck()
try try
@ -4228,7 +4224,7 @@ function! s:Dispatch(bang, cmd, args) abort
try try
let b:current_compiler = 'git' let b:current_compiler = 'git'
let &l:errorformat = s:common_efm let &l:errorformat = s:common_efm
let &l:makeprg = s:shellesc(s:UserCommandList(dir) + s:AskPassArgs(dir) + [a:cmd] + a:args) let &l:makeprg = s:UserCommand(dir, s:AskPassArgs(dir) + [a:cmd] + a:args)
if exists(':Make') == 2 if exists(':Make') == 2
Make Make
return '' return ''