From 340c0bbac53df00c2d0c00d3e626776c4a6016bf Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 11 Jul 2017 23:47:13 +0100 Subject: [PATCH] #756 Escape the paths used for the --include parameter for gometalinter, which uses RE2 --- ale_linters/go/gometalinter.vim | 2 +- autoload/ale/util.vim | 6 ++++++ .../test_gometalinter_command_callback.vader | 6 +++--- test/test_regex_escaping.vader | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 test/test_regex_escaping.vader diff --git a/ale_linters/go/gometalinter.vim b/ale_linters/go/gometalinter.vim index 95251303..26bef321 100644 --- a/ale_linters/go/gometalinter.vim +++ b/ale_linters/go/gometalinter.vim @@ -14,7 +14,7 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'go_gometalinter_options') return ale#Escape(l:executable) - \ . ' --include=' . ale#Escape(l:filename) + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename)) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' ' . ale#Escape(fnamemodify(l:filename, ':h')) endfunction diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index 0fc23d07..c86ac692 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -161,3 +161,9 @@ function! ale#util#FunctionArgCount(function) abort return l:count endfunction + +" Escape a string so the characters in it will be safe for use inside of PCRE +" or RE2 regular expressions without characters having special meanings. +function! ale#util#EscapePCRE(unsafe_string) abort + return substitute(a:unsafe_string, '\([\-\[\]{}()*+?.^$|]\)', '\\\1', 'g') +endfunction diff --git a/test/command_callback/test_gometalinter_command_callback.vader b/test/command_callback/test_gometalinter_command_callback.vader index f1b4e9f0..a0f4da4f 100644 --- a/test/command_callback/test_gometalinter_command_callback.vader +++ b/test/command_callback/test_gometalinter_command_callback.vader @@ -22,7 +22,7 @@ Execute(The gometalinter callback should return the right defaults): \ ale_linters#go#gometalinter#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('gometalinter') - \ . ' --include=' . ale#Escape(expand('%')) + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%'))) \ . ' ' . ale#Escape(getcwd()), \ ale_linters#go#gometalinter#GetCommand(bufnr('')) @@ -34,7 +34,7 @@ Execute(The gometalinter callback should use a configured executable): \ ale_linters#go#gometalinter#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('something else') - \ . ' --include=' . ale#Escape(expand('%')) + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%'))) \ . ' ' . ale#Escape(getcwd()), \ ale_linters#go#gometalinter#GetCommand(bufnr('')) @@ -43,7 +43,7 @@ Execute(The gometalinter callback should use configured options): AssertEqual \ ale#Escape('gometalinter') - \ . ' --include=' . ale#Escape(expand('%')) + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%'))) \ . ' --foobar' \ . ' ' . ale#Escape(getcwd()), \ ale_linters#go#gometalinter#GetCommand(bufnr('')) diff --git a/test/test_regex_escaping.vader b/test/test_regex_escaping.vader new file mode 100644 index 00000000..b79b8c56 --- /dev/null +++ b/test/test_regex_escaping.vader @@ -0,0 +1,4 @@ +Execute(ale#util#EscapePCRE should escape strings for PCRE or RE2 appropriately): + AssertEqual '\\\^\$\*\+\?\.\(\)\|\{\}\[\]', ale#util#EscapePCRE('\^$*+?.()|{}[]') + AssertEqual 'abcABC09', ale#util#EscapePCRE('abcABC09') + AssertEqual '/', ale#util#EscapePCRE('/')