mirror of
https://github.com/vim/vim.git
synced 2025-10-23 08:44:20 -04:00
patch 9.1.1802: 'nowrap' in a modeline may hide malicious code
Problem: 'nowrap' in a modeline may hide malicious code. Solution: Forcibly use '>' as 'listchars' "extends" if 'nowrap' was set from a modeline (zeertzjq). Manual `:setlocal nowrap` disables this behavior. There is a separate problem with `:set nowrap` that also applies to some other options. related: #18214 related: #18399 closes: #18425 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
ad43d2639d
commit
9d5208a931
@@ -1,4 +1,4 @@
|
|||||||
*options.txt* For Vim version 9.1. Last change: 2025 Sep 26
|
*options.txt* For Vim version 9.1. Last change: 2025 Sep 28
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -10259,6 +10259,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
< See 'sidescroll', 'listchars' and |wrap-off|.
|
< See 'sidescroll', 'listchars' and |wrap-off|.
|
||||||
This option can't be set from a |modeline| when the 'diff' option is
|
This option can't be set from a |modeline| when the 'diff' option is
|
||||||
on.
|
on.
|
||||||
|
If 'nowrap' was set from a |modeline| or in the |sandbox|, '>' is used
|
||||||
|
as the |lcs-extends| character regardless of the value of the 'list'
|
||||||
|
and 'listchars' options. This is to prevent malicious code outside
|
||||||
|
the viewport from going unnoticed. Use `:setlocal nowrap` manually
|
||||||
|
afterwards to disable this behavior.
|
||||||
|
|
||||||
*'wrapmargin'* *'wm'*
|
*'wrapmargin'* *'wm'*
|
||||||
'wrapmargin' 'wm' number (default 0)
|
'wrapmargin' 'wm' number (default 0)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*version9.txt* For Vim version 9.1. Last change: 2025 Sep 26
|
*version9.txt* For Vim version 9.1. Last change: 2025 Sep 28
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -41710,6 +41710,9 @@ Options: ~
|
|||||||
- 'rulerformat' now supports the |stl-%!| item
|
- 'rulerformat' now supports the |stl-%!| item
|
||||||
- use 'smoothscroll' logic for CTRL-F / CTRL-B for pagewise scrolling
|
- use 'smoothscroll' logic for CTRL-F / CTRL-B for pagewise scrolling
|
||||||
and CTRL-D / CTRL-U for half-pagewise scrolling
|
and CTRL-D / CTRL-U for half-pagewise scrolling
|
||||||
|
- Setting 'nowrap' in a modeline could cause long lines to be hidden
|
||||||
|
off-screen. To make this visible, the listchars "extend" suboption is set
|
||||||
|
to ">" by default, indicating text that extends beyond the window width.
|
||||||
|
|
||||||
Ex commands: ~
|
Ex commands: ~
|
||||||
- allow to specify a priority when defining a new sign |:sign-define|
|
- allow to specify a priority when defining a new sign |:sign-define|
|
||||||
|
@@ -15,6 +15,22 @@
|
|||||||
|
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the 'listchars' "extends" characters to use for "wp", or NUL if it
|
||||||
|
* shouldn't be used.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_lcs_ext(win_T *wp)
|
||||||
|
{
|
||||||
|
if (wp->w_p_wrap)
|
||||||
|
// Line never continues beyond the right of the screen with 'wrap'.
|
||||||
|
return NUL;
|
||||||
|
if (wp->w_p_wrap_flags & P_INSECURE)
|
||||||
|
// If 'nowrap' was set from a modeline, forcibly use '>'.
|
||||||
|
return '>';
|
||||||
|
return wp->w_p_list ? wp->w_lcs_chars.ext : NUL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FEAT_SYN_HL
|
#ifdef FEAT_SYN_HL
|
||||||
/*
|
/*
|
||||||
* Advance **color_cols and return TRUE when there are columns to draw.
|
* Advance **color_cols and return TRUE when there are columns to draw.
|
||||||
@@ -732,10 +748,7 @@ text_prop_position(
|
|||||||
|
|
||||||
// With 'nowrap' add one to show the "extends" character if needed (it
|
// With 'nowrap' add one to show the "extends" character if needed (it
|
||||||
// doesn't show if the text just fits).
|
// doesn't show if the text just fits).
|
||||||
if (!wp->w_p_wrap
|
if (n_used < *n_extra && get_lcs_ext(wp) != NUL)
|
||||||
&& n_used < *n_extra
|
|
||||||
&& wp->w_lcs_chars.ext != NUL
|
|
||||||
&& wp->w_p_list)
|
|
||||||
++n_used;
|
++n_used;
|
||||||
|
|
||||||
// add 1 for NUL, 2 for when '…' is used
|
// add 1 for NUL, 2 for when '…' is used
|
||||||
@@ -3947,12 +3960,10 @@ win_line(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show "extends" character from 'listchars' if beyond the line end and
|
// Show "extends" character from 'listchars' if beyond the line end.
|
||||||
// 'list' is set.
|
int lcs_ext = get_lcs_ext(wp);
|
||||||
if (wp->w_lcs_chars.ext != NUL
|
if (lcs_ext != NUL
|
||||||
&& wlv.draw_state == WL_LINE
|
&& wlv.draw_state == WL_LINE
|
||||||
&& wp->w_p_list
|
|
||||||
&& !wp->w_p_wrap
|
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
&& wlv.filler_todo <= 0
|
&& wlv.filler_todo <= 0
|
||||||
#endif
|
#endif
|
||||||
@@ -3970,7 +3981,7 @@ win_line(
|
|||||||
#endif
|
#endif
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
c = wp->w_lcs_chars.ext;
|
c = lcs_ext;
|
||||||
wlv.char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT));
|
wlv.char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT));
|
||||||
mb_c = c;
|
mb_c = c;
|
||||||
if (enc_utf8 && utf_char2len(c) > 1)
|
if (enc_utf8 && utf_char2len(c) > 1)
|
||||||
|
@@ -3081,6 +3081,7 @@ insecure_flag(int opt_idx, int opt_flags)
|
|||||||
if (opt_flags & OPT_LOCAL)
|
if (opt_flags & OPT_LOCAL)
|
||||||
switch ((int)options[opt_idx].indir)
|
switch ((int)options[opt_idx].indir)
|
||||||
{
|
{
|
||||||
|
case PV_WRAP: return &curwin->w_p_wrap_flags;
|
||||||
#ifdef FEAT_STL_OPT
|
#ifdef FEAT_STL_OPT
|
||||||
case PV_STL: return &curwin->w_p_stl_flags;
|
case PV_STL: return &curwin->w_p_stl_flags;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4214,6 +4214,7 @@ struct window_S
|
|||||||
#define GLOBAL_WO(p) ((char *)(p) + sizeof(winopt_T))
|
#define GLOBAL_WO(p) ((char *)(p) + sizeof(winopt_T))
|
||||||
|
|
||||||
// A few options have local flags for P_INSECURE.
|
// A few options have local flags for P_INSECURE.
|
||||||
|
long_u w_p_wrap_flags; // flags for 'wrap'
|
||||||
#ifdef FEAT_STL_OPT
|
#ifdef FEAT_STL_OPT
|
||||||
long_u w_p_stl_flags; // flags for 'statusline'
|
long_u w_p_stl_flags; // flags for 'statusline'
|
||||||
#endif
|
#endif
|
||||||
|
@@ -361,4 +361,53 @@ func Test_modeline_disable()
|
|||||||
call assert_equal(2, &sw)
|
call assert_equal(2, &sw)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" If 'nowrap' is set from a modeline, '>' is used forcibly as lcs-extends.
|
||||||
|
func Test_modeline_nowrap_lcs_extends()
|
||||||
|
call writefile([
|
||||||
|
\ 'aaa',
|
||||||
|
\ 'bbb',
|
||||||
|
\ 'ccc evil',
|
||||||
|
\ 'ddd vim: nowrap',
|
||||||
|
\ ], 'Xmodeline_nowrap', 'D')
|
||||||
|
call NewWindow(10, 20)
|
||||||
|
|
||||||
|
setlocal nolist listchars=
|
||||||
|
edit Xmodeline_nowrap
|
||||||
|
let expect_insecure = [
|
||||||
|
\ 'aaa ',
|
||||||
|
\ 'bbb ',
|
||||||
|
\ 'ccc >',
|
||||||
|
\ 'ddd >',
|
||||||
|
\ '~ ',
|
||||||
|
\ ]
|
||||||
|
call assert_equal(expect_insecure, ScreenLines([1, 5], 20))
|
||||||
|
|
||||||
|
setlocal nowrap
|
||||||
|
let expect_secure = [
|
||||||
|
\ 'aaa ',
|
||||||
|
\ 'bbb ',
|
||||||
|
\ 'ccc ',
|
||||||
|
\ 'ddd ',
|
||||||
|
\ '~ ',
|
||||||
|
\ ]
|
||||||
|
call assert_equal(expect_secure, ScreenLines([1, 5], 20))
|
||||||
|
|
||||||
|
setlocal list listchars=extends:+
|
||||||
|
let expect_secure = [
|
||||||
|
\ 'aaa ',
|
||||||
|
\ 'bbb ',
|
||||||
|
\ 'ccc +',
|
||||||
|
\ 'ddd +',
|
||||||
|
\ '~ ',
|
||||||
|
\ ]
|
||||||
|
call assert_equal(expect_secure, ScreenLines([1, 5], 20))
|
||||||
|
|
||||||
|
edit Xmodeline_nowrap
|
||||||
|
call assert_equal(expect_insecure, ScreenLines([1, 5], 20))
|
||||||
|
setlocal nowrap
|
||||||
|
call assert_equal(expect_secure, ScreenLines([1, 5], 20))
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -729,6 +729,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1802,
|
||||||
/**/
|
/**/
|
||||||
1801,
|
1801,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user