Commit: patch 9.2.0176: external diff is allowed in restricted mode

3 views
Skip to first unread message

Christian Brabandt

unread,
Mar 16, 2026, 4:02:03 PM (7 days ago) Mar 16
to vim...@googlegroups.com
patch 9.2.0176: external diff is allowed in restricted mode

Commit: https://github.com/vim/vim/commit/8faba24ca7b2a04771865135c31b4752677da8a3
Author: pyllyukko <pyll...@maimed.org>
Date: Mon Mar 16 19:46:27 2026 +0000

patch 9.2.0176: external diff is allowed in restricted mode

Problem: When 'diffopt' does not include "internal", Vim attempts to
execute an external diff command even in restricted mode.
This could be used to bypass restricted mode.
Solution: Call check_restricted() in diff_file() before attempting to
execute an external diff (pyllyukko).

closes: #19696

Signed-off-by: pyllyukko <pyll...@maimed.org>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 3a722afde..81b4f7d8f 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -52595,6 +52595,9 @@ between them is small (5 bytes or less) and contains only non-word characters.
This prevents fragmented highlighting when only whitespace or punctuation
separates changes.

+Using external diff mode is no longer allowed when Vim is running in
+|restricted-mode|.
+
Other ~
-----
- The new |xdg.vim| script for full XDG compatibility is included.
diff --git a/src/diff.c b/src/diff.c
index 176394724..9ac64d7f6 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1372,6 +1372,9 @@ diff_file(diffio_T *dio)
if (dio->dio_internal)
return diff_file_internal(dio);

+ if (check_restricted())
+ return FAIL;
+
len = STRLEN(tmp_orig) + STRLEN(tmp_new)
+ STRLEN(tmp_diff) + STRLEN(p_srr) + 27;
cmd = alloc(len);
diff --git a/src/testdir/test_restricted.vim b/src/testdir/test_restricted.vim
index 3099dfec1..aa7dc857e 100644
--- a/src/testdir/test_restricted.vim
+++ b/src/testdir/test_restricted.vim
@@ -115,4 +115,27 @@ func Test_restricted_mode()
call delete('Xresult')
endfunc

+" Test that external diff is blocked in restricted mode.
+" Using :diffupdate with 'diffopt' excluding "internal" would call an external
+" diff program via call_shell(), which must be blocked.
+func Test_restricted_diff()
+ let lines =<< trim END
+ set diffopt=filler
+ call writefile(['line1', 'line2'], 'Xrfile1', 'D')
+ call writefile(['line1', 'line3'], 'Xrfile2', 'D')
+ edit Xrfile1
+ diffthis
+ split Xrfile2
+ diffthis
+ call assert_fails('diffupdate', 'E145:')
+ call writefile(v:errors, 'Xresult')
+ qa!
+ END
+ call writefile(lines, 'Xrestricteddiff', 'D')
+ if RunVim([], [], '-Z --clean -S Xrestricteddiff')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xresult')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f4fdeaf98..eff06e5c9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 176,
/**/
175,
/**/
Reply all
Reply to author
Forward
0 new messages