patch 9.2.0299: runtime(zip): may write using absolute paths

Commit: 
https://github.com/vim/vim/commit/46f530e517bd1b59acc2eb0d2aa76d02e54ca9fe
Author: Christian Brabandt <[email protected]>
Date:   Sun Apr 5 15:58:00 2026 +0000

    patch 9.2.0299: runtime(zip): may write using absolute paths
    
    Problem:  runtime(zip): may write using absolute paths
              (syndicate)
    Solution: Detect this case and abort on Unix, warn in the documentation
              about possible issues
    
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index 1ce9cfc2f..f4482fd7f 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -21,6 +21,7 @@
 " 2026 Feb 08 by Vim Project: use system() instead of :!
 " 2026 Mar 08 by Vim Project: Make ZipUpdatePS() check for powershell
 " 2026 Apr 01 by Vim Project: Detect more path traversal attacks
+" 2026 Apr 05 by Vim Project: Detect more path traversal attacks
 " License:     Vim License  (see vim's :help license)
 " Copyright:   Copyright (C) 2005-2019 Charles E. Campbell {{{1
 "              Permission is hereby granted to use and distribute this code,
@@ -395,9 +396,16 @@ fun! zip#Write(fname)
   if has("unix")
     let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\].*$',' ','')
     let fname   = substitute(a:fname,'zipfile://.\{-}::\([^\].*\)$',' ','')
+    " fname should not start with a leading slash to avoid writing anywhere 
into the system
+    if fname =~ '^/'
+      call s:Mess('Error', "***error*** (zip#Write) Path Traversal Attack 
detected, not writing!")
+      call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to 
".curdir."!")
+      return
+    endif
   else
     let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\].*$',' 
','')
     let fname   = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\].*\)$',' 
','')
+    " TODO: what to check on MS-Windows to avoid writing absolute paths?
   endif
   if fname =~ '^[.]\{1,2}/'
     let gnu_cmd = g:zip_zipcmd . ' -d ' . 
s:Escape(fnamemodify(zipfile,":p"),0) . ' ' . s:Escape(fname,0)
diff --git a/runtime/doc/pi_zip.txt b/runtime/doc/pi_zip.txt
index b1bc7fd7d..e9294b405 100644
--- a/runtime/doc/pi_zip.txt
+++ b/runtime/doc/pi_zip.txt
@@ -1,4 +1,4 @@
-*pi_zip.txt*   For Vim version 9.2.  Last change: 2026 Feb 14
+*pi_zip.txt*   For Vim version 9.2.  Last change: 2026 Apr 05
 
                                +====================+
                                | Zip File Interface |
@@ -33,6 +33,10 @@ Copyright: Copyright (C) 2005-2015 Charles E Campbell        
 *zip-copyright*
    also write to the file.  Currently, one may not make a new file in
    zip archives via the plugin.
 
+   The zip plugin tries to detect some common path traversal attack
+   patterns, but it may not catch all possible cases.  Please be very
+   careful when using this plugin with untrusted input.
+
    COMMANDS~
                                                                *zip-x*
    x : extract a listed file when the cursor is atop it
diff --git a/src/testdir/samples/evil.zip b/src/testdir/samples/evil.zip
index 
17cffadf934580090ebe2b3d3876edec14767658..8361710b9bd032d8c4ec094bef18f5884f893fa2
 100644
GIT binary patch
delta 178
zcmbQsyoqJPUQcEg5e5)&sB4XBm=%#P2xNn>3=r#=<QC|cW#-0LWftfs>L=+JBv$6+
zC#L9?RFo9tC+nsa<>%@q7A0q7mZfq{+<h*Nkx7IZw{bud!JvV0H;~3>cz`!68%QZL
O5Q;G}Ft7nJ0|Nj+rz%ze

delta 31
gcmdnQGM9P6-pL${XGB=p7=VBY2+siN-5?GF0D5Kxwg3PC

diff --git a/src/testdir/test_plugin_zip.vim b/src/testdir/test_plugin_zip.vim
index 53b612083..6d7764348 100644
--- a/src/testdir/test_plugin_zip.vim
+++ b/src/testdir/test_plugin_zip.vim
@@ -296,3 +296,22 @@ def g:Test_zip_fname_evil_path2()
   assert_match('zipfile://.*::.*tmp/foobar', @%)
   bw!
 enddef
+
+def g:Test_zip_fname_evil_path3()
+  CheckNotMSWindows
+  # needed for writing the zip file
+  CheckExecutable zip
+
+  CopyZipFile("evil.zip")
+  defer delete("X.zip")
+  e X.zip
+
+  :1
+  var fname = 'payload.txt'
+  search('\V' .. fname)
+  exe "normal \<cr>"
+  :w!
+  var mess  = execute(':mess')
+  assert_match('Path Traversal Attack', mess)
+  bw!
+enddef
diff --git a/src/version.c b/src/version.c
index e3dee3b3a..4d0ec6944 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 */
+/**/
+    299,
 /**/
     298,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1w9Q7u-005V8V-P4%40256bit.org.

Raspunde prin e-mail lui