runtime(gzip): Remove compatibility fall-backs, harden random filename 
generation

Commit: 
https://github.com/vim/vim/commit/ab02d65b1f045607e51a28317894c39ae9512d1d
Author: Yasuhiro Matsumoto <[email protected]>
Date:   Thu Apr 16 19:21:56 2026 +0000

    runtime(gzip): Remove compatibility fall-backs, harden random filename 
generation
    
    Signed-off-by: Yasuhiro Matsumoto <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/autoload/gzip.vim b/runtime/autoload/gzip.vim
index a6fbe2c33..09f35c95b 100644
--- a/runtime/autoload/gzip.vim
+++ b/runtime/autoload/gzip.vim
@@ -1,6 +1,6 @@
 " Vim autoload file for editing compressed files.
 " Maintainer:  The Vim Project <https://github.com/vim/vim>
-" Last Change: 2024 Nov 25
+" Last Change: 2026 Apr 26
 " Former Maintainer: Bram Moolenaar <[email protected]>
 
 " These functions are used by the gzip plugin.
@@ -82,13 +82,8 @@ fun gzip#read(cmd)
   let empty = line("'[") == 1 && line("']") == line("$")
   let tmp = tempname()
   let tmpe = tmp . "." . expand("<afile>:e")
-  if exists('*fnameescape')
-    let tmp_esc = fnameescape(tmp)
-    let tmpe_esc = fnameescape(tmpe)
-  else
-    let tmp_esc = escape(tmp, ' ')
-    let tmpe_esc = escape(tmpe, ' ')
-  endif
+  let tmp_esc = fnameescape(tmp)
+  let tmpe_esc = fnameescape(tmpe)
   " write the just read lines to a temp file "'[,']w tmp.gz"
   execute "silent '[,']w " . tmpe_esc
   " uncompress the temp file: call system("gzip -dn tmp.gz")
@@ -101,22 +96,14 @@ fun gzip#read(cmd)
     let ok = 1
     " delete the compressed lines; remember the line number
     let l = line("'[") - 1
-    if exists(":lockmarks")
-      lockmarks '[,']d _
-    else
-      '[,']d _
-    endif
+    lockmarks '[,']d _
     " read in the uncompressed lines "'[-1r tmp"
     " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options.
     setlocal nobin
-    if exists(":lockmarks")
-      if empty
-       execute "silent lockmarks " . l . "r ++edit " . tmp_esc
-      else
-       execute "silent lockmarks " . l . "r " . tmp_esc
-      endif
+    if empty
+      execute "silent lockmarks " . l . "r ++edit " . tmp_esc
     else
-      execute "silent " . l . "r " . tmp_esc
+      execute "silent lockmarks " . l . "r " . tmp_esc
     endif
 
     " if buffer became empty, delete trailing blank line
@@ -143,11 +130,7 @@ fun gzip#read(cmd)
 
   " When uncompressed the whole buffer, do autocommands
   if ok && empty
-    if exists('*fnameescape')
-      let fname = fnameescape(expand("%:r"))
-    else
-      let fname = escape(expand("%:r"), "      
*?[{`$\%#'\"|!<")
-    endif
+    let fname = fnameescape(expand("%:r"))
     if filereadable(undofile(expand("%")))
       exe "sil rundo " . fnameescape(undofile(expand("%")))
     endif
@@ -191,8 +174,9 @@ fun gzip#appre(cmd)
       call s:set_compression(readfile(nm, "b", 1)[0])
     endif
 
-    " Rename to a weird name to avoid the risk of overwriting another file
-    let nmt = expand("<afile>:p:h") . "/X~=@l9q5"
+    " Rename to a unique name to avoid the risk of overwriting another file
+    " or being targeted by a symlink in a shared directory.
+    let nmt = s:samedir_tempname(nm)
     let nmte = nmt . "." . expand("<afile>:e")
     if rename(nm, nmte) == 0
       if &patchmode != "" && getfsize(nm . &patchmode) == -1
@@ -208,22 +192,27 @@ fun gzip#appre(cmd)
 endfun
 
 " find a file name for the file to be compressed.  Use "name" without an
-" extension if possible.  Otherwise use a weird name to avoid overwriting an
-" existing file.
+" extension if possible.  Otherwise use a unique name to avoid overwriting an
+" existing file or following a symlink set up by another user.
 fun s:tempname(name)
   let fn = fnamemodify(a:name, ":r")
   if !filereadable(fn) && !isdirectory(fn)
     return fn
   endif
-  return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
+  return s:samedir_tempname(a:name)
+endfun
+
+" Generate an unpredictable file name in the same directory as "name", using
+" the random component of tempname() to avoid symlink attacks in shared
+" directories (e.g. /tmp).
+fun s:samedir_tempname(name)
+  let tmp = tempname()
+  return fnamemodify(a:name, ":p:h") . "/" . fnamemodify(tmp, ":h:t") . 
fnamemodify(tmp, ":t")
 endfun
 
 fun s:escape(name)
   " shellescape() was added by patch 7.0.111
-  if exists("*shellescape")
-    return shellescape(a:name)
-  endif
-  return "'" . a:name . "'"
+  return shellescape(a:name)
 endfun
 
 " vim: set sw=2 :

-- 
-- 
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/E1wDSPb-0068G3-L0%40256bit.org.

Raspunde prin e-mail lui