From: Colin Patrick Mccabe Date: Sun, 4 Nov 2012 19:58:45 +0000 (-0800) Subject: add securemodelines.vim X-Git-Url: http://club.cc.cmu.edu/~cmccabe/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2a5368c3faadeb5bc8440a209d24dd232553196;p=cmccabe-etc add securemodelines.vim Signed-off-by: Colin McCabe --- diff --git a/.vim/plugin/securemodelines.vim b/.vim/plugin/securemodelines.vim new file mode 100644 index 0000000..58c3e51 --- /dev/null +++ b/.vim/plugin/securemodelines.vim @@ -0,0 +1,152 @@ +" vim: set sw=4 sts=4 et ft=vim : +" Script: securemodelines.vim +" Author: Ciaran McCreesh +" Homepage: http://github.com/ciaranm/securemodelines +" Requires: Vim 7 +" License: Redistribute under the same terms as Vim itself +" Purpose: A secure alternative to modelines + +if &compatible || v:version < 700 || exists('g:loaded_securemodelines') + finish +endif +let g:loaded_securemodelines = 1 + +if (! exists("g:secure_modelines_allowed_items")) + let g:secure_modelines_allowed_items = [ + \ "textwidth", "tw", + \ "softtabstop", "sts", + \ "tabstop", "ts", + \ "shiftwidth", "sw", + \ "expandtab", "et", "noexpandtab", "noet", + \ "filetype", "ft", + \ "foldmethod", "fdm", + \ "readonly", "ro", "noreadonly", "noro", + \ "rightleft", "rl", "norightleft", "norl", + \ "cindent", "cin", "nocindent", "nocin", + \ "smartindent", "si", "nosmartindent", "nosi", + \ "autoindent", "ai", "noautoindent", "noai", + \ "spell", + \ "spelllang" + \ ] +endif + +if (! exists("g:secure_modelines_verbose")) + let g:secure_modelines_verbose = 0 +endif + +if (! exists("g:secure_modelines_modelines")) + let g:secure_modelines_modelines=5 +endif + +if (! exists("g:secure_modelines_leave_modeline")) + if &modeline + set nomodeline + if g:secure_modelines_verbose + echohl WarningMsg + echo "Forcibly disabling internal modelines for securemodelines.vim" + echohl None + endif + endif +endif + +fun! IsInList(list, i) abort + for l:item in a:list + if a:i == l:item + return 1 + endif + endfor + return 0 +endfun + +fun! DoOne(item) abort + let l:matches = matchlist(a:item, '^\([a-z]\+\)\%([-+^]\?=[a-zA-Z0-9_\-.]\+\)\?$') + if len(l:matches) > 0 + if IsInList(g:secure_modelines_allowed_items, l:matches[1]) + exec "setlocal " . a:item + elseif g:secure_modelines_verbose + echohl WarningMsg + echo "Ignoring '" . a:item . "' in modeline" + echohl None + endif + endif +endfun + +fun! DoNoSetModeline(line) abort + for l:item in split(a:line, '[ \t:]') + call DoOne(l:item) + endfor +endfun + +fun! DoSetModeline(line) abort + for l:item in split(a:line) + call DoOne(l:item) + endfor +endfun + +fun! CheckVersion(op, ver) abort + if a:op == "=" + return v:version != a:ver + elseif a:op == "<" + return v:version < a:ver + elseif a:op == ">" + return v:version >= a:ver + else + return 0 + endif +endfun + +fun! DoModeline(line) abort + let l:matches = matchlist(a:line, '\%(\S\@=]\?\)\([0-9]\+\)\?\)\|\sex\):\s*\%(set\s\+\)\?\([^:]\+\):\S\@!') + if len(l:matches) > 0 + let l:operator = ">" + if len(l:matches[1]) > 0 + let l:operator = l:matches[1] + endif + if len(l:matches[2]) > 0 + if CheckVersion(l:operator, l:matches[2]) ? 0 : 1 + return + endif + endif + return DoSetModeline(l:matches[3]) + endif + + let l:matches = matchlist(a:line, '\%(\S\@=]\?\)\([0-9]\+\)\?\)\|\sex\):\(.\+\)') + if len(l:matches) > 0 + let l:operator = ">" + if len(l:matches[1]) > 0 + let l:operator = l:matches[1] + endif + if len(l:matches[2]) > 0 + if CheckVersion(l:operator, l:matches[2]) ? 0 : 1 + return + endif + endif + return DoNoSetModeline(l:matches[3]) + endif +endfun + +fun! DoModelines() abort + if line("$") > g:secure_modelines_modelines + let l:lines={ } + call map(filter(getline(1, g:secure_modelines_modelines) + + \ getline(line("$") - g:secure_modelines_modelines, "$"), + \ 'v:val =~ ":"'), 'extend(l:lines, { v:val : 0 } )') + for l:line in keys(l:lines) + call DoModeline(l:line) + endfor + else + for l:line in getline(1, "$") + call DoModeline(l:line) + endfor + endif +endfun + +fun! SecureModelines_DoModelines() abort + call DoModelines() +endfun + +aug SecureModeLines + au! + au BufRead,StdinReadPost * :call DoModelines() +aug END +