]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1807: :set doesn't clear local insecure flag like :setlocal does v9.1.1807
authorzeertzjq <zeertzjq@outlook.com>
Mon, 29 Sep 2025 19:26:36 +0000 (19:26 +0000)
committerChristian Brabandt <cb@256bit.org>
Mon, 29 Sep 2025 19:26:36 +0000 (19:26 +0000)
Problem:  :set doesn't clear local insecure flag like :setlocal does.
Solution: Also clear the local insecure flag when using :set (zeertzjq).

This applies to local options like 'wrap', 'foldtext' and 'foldexpr',
whose global flags are actually never used.  For global-local options
like 'statusline' the behavior is already correct, so add some tests.

related: #18434

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/option.c
src/testdir/test_fold.vim
src/testdir/test_modeline.vim
src/testdir/test_statusline.vim
src/version.c

index 4a4d21b8813f5d59025a9d25acd15a2256d5de46..8a495e087ae1846b4986d0fccac2efbcc63fa2af 100644 (file)
@@ -831,6 +831,11 @@ set_option_default(
        // The default value is not insecure.
        flagsp = insecure_flag(opt_idx, opt_flags);
        *flagsp = *flagsp & ~P_INSECURE;
+       if (both)
+       {
+           flagsp = insecure_flag(opt_idx, OPT_LOCAL);
+           *flagsp = *flagsp & ~P_INSECURE;
+       }
     }
 
 #ifdef FEAT_EVAL
@@ -2781,22 +2786,34 @@ did_set_option(
     int            value_checked)  // value was checked to be safe, no need to set the
                            // P_INSECURE flag.
 {
-    long_u     *p;
+    long_u     *flagsp;
+    long_u     *flagsp_local = NULL;
+    int                both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
 
     options[opt_idx].flags |= P_WAS_SET;
 
     // When an option is set in the sandbox, from a modeline or in secure mode
     // set the P_INSECURE flag.  Otherwise, if a new value is stored reset the
     // flag.
-    p = insecure_flag(opt_idx, opt_flags);
+    flagsp = insecure_flag(opt_idx, opt_flags);
+    if (both)
+       flagsp_local = insecure_flag(opt_idx, OPT_LOCAL);
     if (!value_checked && (secure
 #ifdef HAVE_SANDBOX
            || sandbox != 0
 #endif
            || (opt_flags & OPT_MODELINE)))
-       *p = *p | P_INSECURE;
+    {
+       *flagsp = *flagsp | P_INSECURE;
+       if (flagsp_local != NULL)
+           *flagsp_local = *flagsp_local | P_INSECURE;
+    }
     else if (new_value)
-       *p = *p & ~P_INSECURE;
+    {
+       *flagsp = *flagsp & ~P_INSECURE;
+       if (flagsp_local != NULL)
+           *flagsp_local = *flagsp_local & ~P_INSECURE;
+    }
 }
 
 /*
index fc63b1572b0f74b4950ee6d1ca11c259c0fa0d4c..3a00d9c2cdcf79933fd2f96688ea29ed99d1c094 100644 (file)
@@ -1669,7 +1669,7 @@ endfunc
 " in a sandbox
 func Test_foldtext_in_modeline()
   func ModelineFoldText()
-    call feedkeys('aFoo', 'xt')
+    call writefile(['after'], 'Xmodelinefoldtext_write')
     return "folded text"
   endfunc
   let lines =<< trim END
@@ -1680,24 +1680,51 @@ func Test_foldtext_in_modeline()
   END
   call writefile(lines, 'Xmodelinefoldtext', 'D')
 
-  set modeline modelineexpr
-  split Xmodelinefoldtext
+  func Check_foldtext_in_modeline(set_cmd)
+    call writefile(['before'], 'Xmodelinefoldtext_write', 'D')
+    split Xmodelinefoldtext
+    call cursor(1, 1)
+    normal! zf3j
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['before'], readfile('Xmodelinefoldtext_write'))
+
+    setglobal foldtext=ModelineFoldText()
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['before'], readfile('Xmodelinefoldtext_write'))
+
+    setglobal foldtext&
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['before'], readfile('Xmodelinefoldtext_write'))
+
+    exe a:set_cmd 'foldtext=ModelineFoldText()'
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['after'], readfile('Xmodelinefoldtext_write'))
+
+    call writefile(['before'], 'Xmodelinefoldtext_write')
+    exe 'sandbox' a:set_cmd 'foldtext=ModelineFoldText()'
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['before'], readfile('Xmodelinefoldtext_write'))
+
+    exe a:set_cmd 'foldtext=ModelineFoldText()'
+    call assert_equal('folded text', foldtextresult(1))
+    call assert_equal(['after'], readfile('Xmodelinefoldtext_write'))
+    bw!
+  endfunc
 
-  call cursor(1, 1)
-  normal! zf3j
-  call assert_equal('folded text', foldtextresult(1))
-  call assert_equal(lines, getbufline('', 1, '$'))
+  set modeline modelineexpr
+  call Check_foldtext_in_modeline('setlocal')
+  call Check_foldtext_in_modeline('set')
 
-  bw!
   set modeline& modelineexpr&
   delfunc ModelineFoldText
+  delfunc Check_foldtext_in_modeline
 endfunc
 
 " Test for setting 'foldexpr' from the modeline and executing the expression
 " in a sandbox
 func Test_foldexpr_in_modeline()
   func ModelineFoldExpr()
-    call feedkeys('aFoo', 'xt')
+    call writefile(['after'], 'Xmodelinefoldexpr_write')
     return strlen(matchstr(getline(v:lnum),'^\s*'))
   endfunc
   let lines =<< trim END
@@ -1711,15 +1738,42 @@ func Test_foldexpr_in_modeline()
   END
   call writefile(lines, 'Xmodelinefoldexpr', 'D')
 
-  set modeline modelineexpr
-  split Xmodelinefoldexpr
+  func Check_foldexpr_in_modeline(set_cmd)
+    call writefile(['before'], 'Xmodelinefoldexpr_write', 'D')
+    split Xmodelinefoldexpr
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['before'], readfile('Xmodelinefoldexpr_write'))
 
-  call assert_equal(2, foldlevel(3))
-  call assert_equal(lines, getbufline('', 1, '$'))
+    setglobal foldexpr=ModelineFoldExpr()
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['before'], readfile('Xmodelinefoldexpr_write'))
+
+    setglobal foldexpr&
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['before'], readfile('Xmodelinefoldexpr_write'))
+
+    exe a:set_cmd 'foldexpr=ModelineFoldExpr()'
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['after'], readfile('Xmodelinefoldexpr_write'))
+
+    call writefile(['before'], 'Xmodelinefoldexpr_write')
+    exe 'sandbox' a:set_cmd 'foldexpr=ModelineFoldExpr()'
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['before'], readfile('Xmodelinefoldexpr_write'))
+
+    exe a:set_cmd 'foldexpr=ModelineFoldExpr()'
+    call assert_equal(2, foldlevel(3))
+    call assert_equal(['after'], readfile('Xmodelinefoldexpr_write'))
+    bw!
+  endfunc
+
+  set modeline modelineexpr
+  call Check_foldexpr_in_modeline('setlocal')
+  call Check_foldexpr_in_modeline('set')
 
-  bw!
   set modeline& modelineexpr&
   delfunc ModelineFoldExpr
+  delfunc Check_foldexpr_in_modeline
 endfunc
 
 " Make sure a fold containing a nested fold is split correctly when using
index a5762f7f6b212ff31af30cac2f71749b410db35b..cb144c580a1d21ac794c63c319e02c423d3036f8 100644 (file)
@@ -371,8 +371,22 @@ func Test_modeline_nowrap_lcs_extends()
         \ ], 'Xmodeline_nowrap', 'D')
   call NewWindow(10, 20)
 
+  func Check_modeline_nowrap(expect_insecure, expect_secure, set_cmd)
+    edit Xmodeline_nowrap
+    call assert_equal(a:expect_insecure, ScreenLines([1, 5], 20))
+    setglobal nowrap
+    call assert_equal(a:expect_insecure, ScreenLines([1, 5], 20))
+    setglobal wrap
+    call assert_equal(a:expect_insecure, ScreenLines([1, 5], 20))
+    exe a:set_cmd 'nowrap'
+    call assert_equal(a:expect_secure, ScreenLines([1, 5], 20))
+    exe 'sandbox' a:set_cmd 'nowrap'
+    call assert_equal(a:expect_insecure, ScreenLines([1, 5], 20))
+    exe a:set_cmd 'nowrap'
+    call assert_equal(a:expect_secure, ScreenLines([1, 5], 20))
+  endfunc
+
   setlocal nolist listchars=
-  edit Xmodeline_nowrap
   let expect_insecure = [
         \ 'aaa                 ',
         \ 'bbb                 ',
@@ -380,9 +394,6 @@ func Test_modeline_nowrap_lcs_extends()
         \ 'ddd                >',
         \ '~                   ',
         \ ]
-  call assert_equal(expect_insecure, ScreenLines([1, 5], 20))
-
-  setlocal nowrap
   let expect_secure = [
         \ 'aaa                 ',
         \ 'bbb                 ',
@@ -390,7 +401,8 @@ func Test_modeline_nowrap_lcs_extends()
         \ 'ddd                 ',
         \ '~                   ',
         \ ]
-  call assert_equal(expect_secure, ScreenLines([1, 5], 20))
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'setlocal')
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'set')
 
   setlocal list listchars=extends:+
   let expect_secure = [
@@ -401,13 +413,45 @@ func Test_modeline_nowrap_lcs_extends()
         \ '~                   ',
         \ ]
   call assert_equal(expect_secure, ScreenLines([1, 5], 20))
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'setlocal')
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'set')
 
-  edit Xmodeline_nowrap
-  call assert_equal(expect_insecure, ScreenLines([1, 5], 20))
-  setlocal nowrap
-  call assert_equal(expect_secure, ScreenLines([1, 5], 20))
+  " Other 'listchars' flags are not affected.
+  call writefile([
+        \ "aa\ta",
+        \ "bb\tb",
+        \ "cc\tc              evil",
+        \ "dd\td              vim: nowrap lcs=tab\\:<->",
+        \ ], 'Xmodeline_nowrap')
+  let expect_insecure = [
+        \ 'aa<---->a           ',
+        \ 'bb<---->b           ',
+        \ 'cc<---->c          >',
+        \ 'dd<---->d          >',
+        \ '~                   ',
+        \ ]
+  let expect_secure = [
+        \ 'aa<---->a           ',
+        \ 'bb<---->b           ',
+        \ 'cc<---->c           ',
+        \ 'dd<---->d           ',
+        \ '~                   ',
+        \ ]
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'setlocal')
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'set')
+
+  " Same behavior even if modeline sets "extends" to a space.
+  call writefile([
+        \ "aa\ta",
+        \ "bb\tb",
+        \ "cc\tc              evil",
+        \ "dd\td              vim: nowrap lcs=tab\\:<->",
+        \ ], 'Xmodeline_nowrap')
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'setlocal')
+  call Check_modeline_nowrap(expect_insecure, expect_secure, 'set')
 
   call CloseWindow()
+  delfunc Check_modeline_nowrap
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
index 401eb2a046b8278b8d5b5f181c4e3aac4a231839..e1f63594017f7aaa5848c1283446308f9e21c04c 100644 (file)
@@ -637,4 +637,47 @@ func Test_statusline_highlight_group_cleared()
   call StopVimInTerminal(buf)
 endfunc
 
+" Test for setting both global and local 'statusline' values in a sandbox
+func Test_statusline_in_sandbox()
+  func SandboxStatusLine()
+    call writefile(['after'], 'Xsandboxstatusline_write')
+    return "status line"
+  endfunc
+
+  func Check_statusline_in_sandbox(set_cmd0, set_cmd1)
+    new | only
+    call writefile(['before'], 'Xsandboxstatusline_write', 'D')
+    setlocal statusline=
+    exe 'sandbox' a:set_cmd0 'statusline=%!SandboxStatusLine()'
+    call assert_equal('', &l:statusline)
+    sandbox setlocal statusline=%!SandboxStatusLine()
+    call assert_fails('redrawstatus', 'E48:')
+    call assert_equal(['before'], readfile('Xsandboxstatusline_write'))
+
+    setlocal statusline=%!SandboxStatusLine() | redrawstatus
+    call assert_equal('status line', Screenline(&lines - 1))
+    call assert_equal(['after'], readfile('Xsandboxstatusline_write'))
+
+    call writefile(['before'], 'Xsandboxstatusline_write')
+    setlocal statusline=
+    call assert_fails('redrawstatus', 'E48:')
+    call assert_equal(['before'], readfile('Xsandboxstatusline_write'))
+
+    exe a:set_cmd1 'statusline=%!SandboxStatusLine()' | redrawstatus
+    call assert_equal('', &l:statusline)
+    call assert_equal('status line', Screenline(&lines - 1))
+    call assert_equal(['after'], readfile('Xsandboxstatusline_write'))
+    bw!
+  endfunc
+
+  call Check_statusline_in_sandbox('setglobal', 'setglobal')
+  call Check_statusline_in_sandbox('setglobal', 'set')
+  call Check_statusline_in_sandbox('set', 'setglobal')
+  call Check_statusline_in_sandbox('set', 'set')
+
+  set statusline&
+  delfunc SandboxStatusLine
+  delfunc Check_statusline_in_sandbox
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 900a682f884c0af9be44d0149ce0f25a844b1821..ba653958a5f4b38d3f53910c37a65c0aa5e03d4a 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1807,
 /**/
     1806,
 /**/