Fix #549 - escape strings more appropriately for use with cmd /c
This commit is contained in:
parent
fb07971290
commit
c89587785b
2 changed files with 59 additions and 5 deletions
|
@ -135,14 +135,26 @@ function! ale#Set(variable_name, default) abort
|
|||
return l:value
|
||||
endfunction
|
||||
|
||||
function! s:EscapePercents(str) abort
|
||||
return substitute(a:str, '%', '%%', 'g')
|
||||
endfunction
|
||||
|
||||
" Escape a string suitably for each platform.
|
||||
" shellescape does not work on Windows.
|
||||
function! ale#Escape(str) abort
|
||||
if fnamemodify(&shell, ':t') ==? 'cmd.exe'
|
||||
" FIXME: Fix shell escaping for Windows.
|
||||
return fnameescape(a:str)
|
||||
else
|
||||
" An extra space is used here to disable the custom-checks.
|
||||
return shellescape (a:str)
|
||||
if a:str =~# '\v^[a-zA-Z0-9-_\\/:%]+$'
|
||||
return s:EscapePercents(a:str)
|
||||
endif
|
||||
|
||||
if a:str =~# ' '
|
||||
return '"'
|
||||
\ . substitute(s:EscapePercents(a:str), '"', '""', 'g')
|
||||
\ . '"'
|
||||
endif
|
||||
|
||||
return s:EscapePercents(substitute(a:str, '\v([&|<>^])', '^\1', 'g'))
|
||||
endif
|
||||
|
||||
return shellescape (a:str)
|
||||
endfunction
|
||||
|
|
42
test/test_windows_escaping.vader
Normal file
42
test/test_windows_escaping.vader
Normal file
|
@ -0,0 +1,42 @@
|
|||
Before:
|
||||
Save &shell
|
||||
let &shell = 'cmd.exe'
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
Execute(ale#Escape for cmd.exe should allow not escape paths without special characters):
|
||||
AssertEqual 'C:', ale#Escape('C:')
|
||||
AssertEqual 'C:\', ale#Escape('C:\')
|
||||
AssertEqual 'python', ale#Escape('python')
|
||||
AssertEqual 'C:\foo\bar', ale#Escape('C:\foo\bar')
|
||||
AssertEqual '/bar/baz', ale#Escape('/bar/baz')
|
||||
AssertEqual 'nul', ale#Escape('nul')
|
||||
AssertEqual '''foo''', ale#Escape('''foo''')
|
||||
|
||||
Execute(ale#Escape for cmd.exe should escape Windows paths with spaces appropriately):
|
||||
AssertEqual '"C:\foo bar\baz"', ale#Escape('C:\foo bar\baz')
|
||||
AssertEqual '"^foo bar^"', ale#Escape('^foo bar^')
|
||||
AssertEqual '"&foo bar&"', ale#Escape('&foo bar&')
|
||||
AssertEqual '"|foo bar|"', ale#Escape('|foo bar|')
|
||||
AssertEqual '"<foo bar<"', ale#Escape('<foo bar<')
|
||||
AssertEqual '">foo bar>"', ale#Escape('>foo bar>')
|
||||
AssertEqual '"^foo bar^"', ale#Escape('^foo bar^')
|
||||
AssertEqual '"''foo'' ''bar''"', ale#Escape('''foo'' ''bar''')
|
||||
|
||||
Execute(ale#Escape for cmd.exe should use caret escapes on special characters):
|
||||
AssertEqual '^^foo^^', ale#Escape('^foo^')
|
||||
AssertEqual '^&foo^&', ale#Escape('&foo&')
|
||||
AssertEqual '^|foo^|', ale#Escape('|foo|')
|
||||
AssertEqual '^<foo^<', ale#Escape('<foo<')
|
||||
AssertEqual '^>foo^>', ale#Escape('>foo>')
|
||||
AssertEqual '^^foo^^', ale#Escape('^foo^')
|
||||
AssertEqual '''foo''^^''bar''', ale#Escape('''foo''^''bar''')
|
||||
|
||||
Execute(ale#Escape for cmd.exe should escape percent characters):
|
||||
AssertEqual '%%foo%%', ale#Escape('%foo%')
|
||||
AssertEqual 'C:\foo%%\bar\baz%%', ale#Escape('C:\foo%\bar\baz%')
|
||||
AssertEqual '"C:\foo bar%%\baz%%"', ale#Escape('C:\foo bar%\baz%')
|
||||
AssertEqual '^^%%foo%%', ale#Escape('^%foo%')
|
||||
AssertEqual '"^%%foo%% %%bar%%"', ale#Escape('^%foo% %bar%')
|
||||
AssertEqual '"^%%foo%% %%bar%% """""', ale#Escape('^%foo% %bar% ""')
|
Reference in a new issue