Account for 'shellslash' being set on Windows

If a user has 'shellslash' set in Windows, then filename related
functionality uses forward slashes instead of backslashes.  This breaks
running of external commands because some external commands in Windows
treat any forward slash as a command line switch.

This change adds s:shellescape(), which wraps Vim's shellescape(), but
ensures 'noshellslash' is set first in Windows command prompt (not
Cygwin or msys) environments.  Having 'noshellslash' set when
shellescape() is called causes the string to be quoted, regardless of
whether there is whitespace or typical special characters, thus avoiding
the interpretation of the string as being command line switches.

Closes jamessan/vim-gnupg#41
Signed-off-by: James McCoy <vega.james@gmail.com>
This commit is contained in:
James McCoy 2015-09-29 19:48:18 -04:00
parent 89253464f1
commit f12d007414
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB

View File

@ -214,6 +214,29 @@ highlight default link GPGHighlightUnknownRecipient ErrorMsg
" Section: Functions {{{1
" Function: s:shellescape(s[, special]) {{{2
"
" Calls shellescape(), also taking into account 'shellslash'
" when on Windows and using $COMSPEC as the shell.
"
" Returns: shellescaped string
"
function s:shellescape(s, ...)
let special = a:0 ? a:1 : 0
if exists('+shellslash') && &shell == $COMSPEC
let ssl = &shellslash
set noshellslash
let escaped = shellescape(a:s, special)
let &shellslash = ssl
else
let escaped = shellescape(a:s, special)
endif
return escaped
endfunction
" Function: s:GPGInit(bufread) {{{2
"
" initialize the plugin
@ -447,7 +470,7 @@ function s:GPGDecrypt(bufread)
" find the recipients of the file
let cmd = { 'level': 3 }
let cmd.args = '--verbose --decrypt --list-only --dry-run --no-use-agent --logger-fd 1 ' . shellescape(filename)
let cmd.args = '--verbose --decrypt --list-only --dry-run --no-use-agent --logger-fd 1 ' . s:shellescape(filename)
let output = s:GPGSystem(cmd)
" Suppress the "N more lines" message when editing a file, not when reading
@ -530,7 +553,7 @@ function s:GPGDecrypt(bufread)
" we must redirect stderr (using shell temporarily)
call s:GPGDebug(1, "decrypting file")
let cmd = { 'level': 1, 'ex': silent . 'r !' }
let cmd.args = '--quiet --decrypt ' . shellescape(filename, 1)
let cmd.args = '--quiet --decrypt ' . s:shellescape(filename, 1)
call s:GPGExecute(cmd)
if (v:shell_error) " message could not be decrypted
@ -666,7 +689,7 @@ function s:GPGEncrypt()
let destfile = tempname()
let cmd = { 'level': 1, 'ex': "'[,']w !" }
let cmd.args = '--quiet --no-encrypt-to ' . options
let cmd.redirect = '>' . shellescape(destfile, 1)
let cmd.redirect = '>' . s:shellescape(destfile, 1)
silent call s:GPGExecute(cmd)
" restore encoding
@ -1157,7 +1180,7 @@ function s:GPGNameToID(name)
" ask gpg for the id for a name
let cmd = { 'level': 2 }
let cmd.args = '--quiet --with-colons --fixed-list-mode --list-keys ' . shellescape(a:name)
let cmd.args = '--quiet --with-colons --fixed-list-mode --list-keys ' . s:shellescape(a:name)
let output = s:GPGSystem(cmd)
" when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8,
@ -1322,7 +1345,7 @@ endfunction
function s:GPGSystem(dict)
let commandline = s:GPGCommand
if (!empty(g:GPGHomedir))
let commandline .= ' --homedir ' . shellescape(g:GPGHomedir)
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir)
endif
let commandline .= ' ' . a:dict.args
let commandline .= ' ' . s:stderrredirnull
@ -1349,7 +1372,7 @@ endfunction
function s:GPGExecute(dict)
let commandline = printf('%s%s', a:dict.ex, s:GPGCommand)
if (!empty(g:GPGHomedir))
let commandline .= ' --homedir ' . shellescape(g:GPGHomedir, 1)
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir, 1)
endif
let commandline .= ' ' . a:dict.args
if (has_key(a:dict, 'redirect'))