From 92e6e4d1ba482a4d2d89d850f660c67ccf8a28eb Mon Sep 17 00:00:00 2001 From: Anthony DeDominic Date: Wed, 14 Mar 2018 13:46:57 -0400 Subject: [PATCH] Fix awk linter and security concerns. (#1411) * Fixed (g)awk linter * Made it secure, albeit less useful. * Added gawk handler; the cpplint one was not working? * Added gawk handler test. * added warning to gawk handler. * added gawk command callback test * added comment about --source * added back optional commandline option --- ale_linters/awk/gawk.vim | 6 ++- autoload/ale/handlers/gawk.vim | 25 ++++++++++++ .../test_gawk_command_callback.vader | 40 +++++++++++++++++++ test/handler/test_gawk_handler.vader | 39 ++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 autoload/ale/handlers/gawk.vim create mode 100644 test/command_callback/test_gawk_command_callback.vader create mode 100644 test/handler/test_gawk_handler.vader diff --git a/ale_linters/awk/gawk.vim b/ale_linters/awk/gawk.vim index ac6e915..3e9987b 100644 --- a/ale_linters/awk/gawk.vim +++ b/ale_linters/awk/gawk.vim @@ -12,7 +12,11 @@ function! ale_linters#awk#gawk#GetExecutable(buffer) abort endfunction function! ale_linters#awk#gawk#GetCommand(buffer) abort + " note the --source 'BEGIN ...' is to prevent + " gawk from attempting to execute the body of the script + " it is linting. return ale_linters#awk#gawk#GetExecutable(a:buffer) + \ . " --source 'BEGIN { exit } END { exit 1 }'" \ . ' ' . ale#Var(a:buffer, 'awk_gawk_options') \ . ' ' . '-f %t --lint /dev/null' endfunction @@ -21,6 +25,6 @@ call ale#linter#Define('awk', { \ 'name': 'gawk', \ 'executable_callback': 'ale_linters#awk#gawk#GetExecutable', \ 'command_callback': 'ale_linters#awk#gawk#GetCommand', -\ 'callback': 'ale#handlers#cpplint#HandleCppLintFormat', +\ 'callback': 'ale#handlers#gawk#HandleGawkFormat', \ 'output_stream': 'both' \}) diff --git a/autoload/ale/handlers/gawk.vim b/autoload/ale/handlers/gawk.vim new file mode 100644 index 0000000..942bc2b --- /dev/null +++ b/autoload/ale/handlers/gawk.vim @@ -0,0 +1,25 @@ +" Author: Anthony DeDominic +" Description: Handle output from gawk's --lint option + +function! ale#handlers#gawk#HandleGawkFormat(buffer, lines) abort + " Look for lines like the following: + " gawk: /tmp/v0fddXz/1/something.awk:1: ^ invalid char ''' in expression + let l:pattern = '^.\{-}:\(\d\+\):\s\+\(warning:\|\^\)\s*\(.*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:ecode = 'E' + if l:match[2] is? 'warning:' + let l:ecode = 'W' + endif + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': 0, + \ 'text': l:match[3], + \ 'code': 0, + \ 'type': l:ecode, + \}) + endfor + + return l:output +endfunction diff --git a/test/command_callback/test_gawk_command_callback.vader b/test/command_callback/test_gawk_command_callback.vader new file mode 100644 index 0000000..ae128fe --- /dev/null +++ b/test/command_callback/test_gawk_command_callback.vader @@ -0,0 +1,40 @@ +Before: + Save g:ale_awk_gawk_executable + Save g:ale_awk_gawk_options + unlet! g:ale_awk_gawk_executable + unlet! g:ale_awk_gawk_options + + runtime ale_linters/awk/gawk.vim + +After: + Restore + unlet! b:command_tail + unlet! b:ale_awk_gawk_executable + unlet! b:ale_awk_gawk_options + + call ale#linter#Reset() + +Execute(The executable should be used in the command): + AssertEqual + \ 'gawk' + \ . " --source 'BEGIN { exit } END { exit 1 }'" + \ . ' ' . '-f %t --lint /dev/null', + \ ale_linters#awk#gawk#GetCommand(bufnr('')) + + let b:ale_awk_gawk_executable = '/other/gawk' + + AssertEqual + \ '/other/gawk' + \ . " --source 'BEGIN { exit } END { exit 1 }'" + \ . ' ' . '-f %t --lint /dev/null', + \ ale_linters#awk#gawk#GetCommand(bufnr('')) + + let b:ale_awk_gawk_executable = 'gawk' + let b:ale_awk_gawk_options = '--something' + + AssertEqual + \ 'gawk' + \ . " --source 'BEGIN { exit } END { exit 1 }'" + \ . ' --something' + \ . ' ' . '-f %t --lint /dev/null', + \ ale_linters#awk#gawk#GetCommand(bufnr('')) diff --git a/test/handler/test_gawk_handler.vader b/test/handler/test_gawk_handler.vader new file mode 100644 index 0000000..3a7b545 --- /dev/null +++ b/test/handler/test_gawk_handler.vader @@ -0,0 +1,39 @@ +Before: + runtime ale_linters/awk/gawk.vim + +After: + call ale#linter#Reset() + +Execute(gawk syntax errors should be parsed correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 0, + \ 'text': "invalid char ''' in expression", + \ 'code': 0, + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 0, + \ 'text': 'unterminated string', + \ 'code': 0, + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 10, + \ 'col': 0, + \ 'text': "escape sequence `\u' treated as plain `u'", + \ 'code': 0, + \ 'type': 'W', + \ }, + \ ], + \ ale#handlers#gawk#HandleGawkFormat(347, [ + \ "gawk: something.awk:1: BEGIN { system('touch aaaaaaaaa') }", + \ "gawk: something.awk:1: ^ invalid char ''' in expression", + \ 'gawk: something.awk:5: { x = "aaaaaaaaaaa', + \ 'gawk: something.awk:5: ^ unterminated string', + \ "gawk: something.awk:10: warning: escape sequence `\u' treated as plain `u'", + \ ])