Mercurial > vim
view src/testdir/test_history.vim @ 33664:06b59278bfcf v9.0.2070
patch 9.0.2070: [security] disallow setting env in restricted mode
Commit: https://github.com/vim/vim/commit/6b89dd6a7257a1e2e9c7ea070b407bc4674a5118
Author: Christian Brabandt <cb@256bit.org>
Date: Thu Oct 26 22:14:17 2023 +0200
patch 9.0.2070: [security] disallow setting env in restricted mode
Problem: [security] disallow setting env in restricted mode
Solution: Setting environment variables in restricted mode could
potentially be used to execute shell commands. Disallow this.
restricted mode: disable allow setting of environment variables
Setting environment variables in restricted mode, may have some unwanted
consequences. So, for example by setting $GCONV_PATH in restricted mode
and then calling the iconv() function, one may be able to execute some
unwanted payload, because the `iconv_open()` function internally uses
the `$GCONV_PATH` variable to find its conversion data.
So let's disable setting environment variables, even so this is no
complete protection, since we are not clearing the existing environment.
I tried a few ways but wasn't successful :(
One could also argue to disable the iconv() function completely in
restricted mode, but who knows what other API functions can be
influenced by setting some other unrelated environment variables.
So let's leave it as it is currently.
closes: #13394
See: https://huntr.com/bounties/b0a2eda1-459c-4e36-98e6-0cc7d7faccfe/
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 26 Oct 2023 22:30:03 +0200 |
parents | ca0229869b38 |
children | 75f7b311ee25 |
line wrap: on
line source
" Tests for the history functions source check.vim CheckFeature cmdline_hist set history=7 function History_Tests(hist) " First clear the history call histadd(a:hist, 'dummy') call assert_true(histdel(a:hist)) call assert_equal(-1, histnr(a:hist)) call assert_equal('', histget(a:hist)) call assert_true('ls'->histadd(a:hist)) call assert_true(histadd(a:hist, 'buffers')) call assert_equal('buffers', histget(a:hist)) call assert_equal('ls', histget(a:hist, -2)) call assert_equal('ls', histget(a:hist, 1)) call assert_equal('', histget(a:hist, 5)) call assert_equal('', histget(a:hist, -5)) call assert_equal(2, histnr(a:hist)) call assert_true(histdel(a:hist, 2)) call assert_false(a:hist->histdel(7)) call assert_equal(1, histnr(a:hist)) call assert_equal('ls', histget(a:hist, -1)) call assert_true(histadd(a:hist, 'buffers')) call assert_true(histadd(a:hist, 'ls')) call assert_equal('ls', a:hist->histget(-1)) call assert_equal(4, a:hist->histnr()) let a=execute('history ' . a:hist) call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) let a=execute('history all') call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a) if len(a:hist) > 0 let a=execute('history ' . a:hist . ' 2') call assert_match("^\n # \\S* history$", a) let a=execute('history ' . a:hist . ' 3') call assert_match("^\n # \\S* history\n 3 buffers$", a) let a=execute('history ' . a:hist . ' 4') call assert_match("^\n # \\S* history\n> 4 ls$", a) let a=execute('history ' . a:hist . ' 3,4') call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) let a=execute('history ' . a:hist . ' -1') call assert_match("^\n # \\S* history\n> 4 ls$", a) let a=execute('history ' . a:hist . ' -2') call assert_match("^\n # \\S* history\n 3 buffers$", a) let a=execute('history ' . a:hist . ' -2,') call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) let a=execute('history ' . a:hist . ' -3') call assert_match("^\n # \\S* history$", a) endif " Test for removing entries matching a pattern for i in range(1, 3) call histadd(a:hist, 'text_' . i) endfor call assert_true(histdel(a:hist, 'text_\d\+')) call assert_equal('ls', histget(a:hist, -1)) " Test for freeing the entire history list for i in range(1, 7) call histadd(a:hist, 'text_' . i) endfor call histdel(a:hist) for i in range(1, 7) call assert_equal('', histget(a:hist, i)) call assert_equal('', histget(a:hist, i - 7 - 1)) endfor " Test for freeing an entry at the beginning of the history list for i in range(1, 4) call histadd(a:hist, 'text_' . i) endfor call histdel(a:hist, 1) call assert_equal('', histget(a:hist, 1)) call assert_equal('text_4', histget(a:hist, 4)) endfunction function Test_History() for h in ['cmd', ':', '', 'search', '/', '?', 'expr', '=', 'input', '@', 'debug', '>'] call History_Tests(h) endfor " Negative tests call assert_false(histdel('abc')) call assert_equal('', histget('abc')) call assert_fails('call histdel([])', 'E730:') call assert_equal('', histget(10)) call assert_fails('call histget([])', 'E730:') call assert_equal(-1, histnr('abc')) call assert_fails('call histnr([])', 'E730:') call assert_fails('history xyz', 'E488:') call assert_fails('history ,abc', 'E488:') call assert_fails('call histdel(":", "\\%(")', 'E53:') endfunction function Test_history_truncates_long_entry() " History entry short enough to fit on the screen should not be truncated. call histadd(':', 'echo x' .. repeat('y', &columns - 17) .. 'z') let a = execute('history : -1') call assert_match("^\n # cmd history\n" \ .. "> *\\d\\+ echo x" .. repeat('y', &columns - 17) .. 'z$', a) " Long history entry should be truncated to fit on the screen, with, '...' " inserted in the string to indicate the that there is truncation. call histadd(':', 'echo x' .. repeat('y', &columns - 16) .. 'z') let a = execute('history : -1') call assert_match("^\n # cmd history\n" \ .. "> *\\d\\+ echo xy\\+\.\.\.y\\+z$", a) endfunction function Test_Search_history_window() new call setline(1, ['a', 'b', 'a', 'b']) 1 call feedkeys("/a\<CR>", 'xt') call assert_equal('a', getline('.')) 1 call feedkeys("/b\<CR>", 'xt') call assert_equal('b', getline('.')) 1 " select the previous /a command call feedkeys("q/kk\<CR>", 'x!') call assert_equal('a', getline('.')) call assert_equal('a', @/) bwipe! endfunc " Test for :history command option completion function Test_history_completion() call feedkeys(":history \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"history / : = > ? @ all cmd debug expr input search', @:) endfunc " Test for increasing the 'history' option value func Test_history_size() let save_histsz = &history set history=10 call histadd(':', 'ls') call histdel(':') for i in range(1, 5) call histadd(':', 'cmd' .. i) endfor call assert_equal(5, histnr(':')) call assert_equal('cmd5', histget(':', -1)) set history=15 for i in range(6, 10) call histadd(':', 'cmd' .. i) endfor call assert_equal(10, histnr(':')) call assert_equal('cmd1', histget(':', 1)) call assert_equal('cmd10', histget(':', -1)) set history=5 call histadd(':', 'abc') call assert_equal('', histget(':', 6)) call assert_equal('', histget(':', 12)) call assert_equal('cmd7', histget(':', 7)) call assert_equal('abc', histget(':', -1)) " This test works only when the language is English if v:lang == "C" || v:lang =~ '^[Ee]n' set history=0 redir => v call feedkeys(":history\<CR>", 'xt') redir END call assert_equal(["'history' option is zero"], split(v, "\n")) endif let &history=save_histsz endfunc " Test for recalling old search patterns in / func Test_history_search() call histdel('/') let g:pat = [] func SavePat() call add(g:pat, getcmdline()) return '' endfunc cnoremap <F2> <C-\>eSavePat()<CR> call histadd('/', 'pat1') call histadd('/', 'pat2') let @/ = '' call feedkeys("/\<Up>\<F2>\<Up>\<F2>\<Down>\<Down>\<F2>\<Esc>", 'xt') call assert_equal(['pat2', 'pat1', ''], g:pat) cunmap <F2> delfunc SavePat " Search for a pattern that is not present in the history call assert_beeps('call feedkeys("/a1b2\<Up>\<CR>", "xt")') " Recall patterns with 'history' set to 0 set history=0 let @/ = 'abc' let cmd = 'call feedkeys("/\<Up>\<Down>\<S-Up>\<S-Down>\<CR>", "xt")' call assert_fails(cmd, 'E486:') set history& " Recall patterns till the end of history set history=4 call histadd('/', 'pat') call histdel('/') call histadd('/', 'pat1') call histadd('/', 'pat2') call assert_beeps('call feedkeys("/\<Up>\<Up>\<Up>\<C-U>\<cr>", "xt")') call assert_beeps('call feedkeys("/\<Down><cr>", "xt")') " Test for wrapping around the history list for i in range(3, 7) call histadd('/', 'pat' .. i) endfor let upcmd = "\<up>\<up>\<up>\<up>\<up>" let downcmd = "\<down>\<down>\<down>\<down>\<down>" try call feedkeys("/" .. upcmd .. "\<cr>", 'xt') catch /E486:/ endtry call assert_equal('pat4', @/) try call feedkeys("/" .. upcmd .. downcmd .. "\<cr>", 'xt') catch /E486:/ endtry call assert_equal('pat4', @/) " Test for changing the search command separator in the history call assert_fails('call feedkeys("/def/\<cr>", "xt")', 'E486:') call assert_fails('call feedkeys("?\<up>\<cr>", "xt")', 'E486:') call assert_equal('def?', histget('/', -1)) call assert_fails('call feedkeys("/ghi?\<cr>", "xt")', 'E486:') call assert_fails('call feedkeys("?\<up>\<cr>", "xt")', 'E486:') call assert_equal('ghi\?', histget('/', -1)) set history& endfunc " Test for making sure the key value is not stored in history func Test_history_crypt_key() CheckFeature cryptv call feedkeys(":set bs=2 key=abc ts=8\<CR>", 'xt') call assert_equal('set bs=2 key= ts=8', histget(':')) call assert_fails("call feedkeys(':set bs=2 key-=abc ts=8\<CR>', 'xt')") call assert_equal('set bs=2 key-= ts=8', histget(':')) set key& bs& ts& endfunc " The following used to overflow and causing an use-after-free func Test_history_max_val() set history=10 call assert_fails(':history 2147483648', 'E1510:') set history& endfunc " vim: shiftwidth=2 sts=2 expandtab