patch 9.2.0306: runtime(tar): some issues with lz4 support
Commit:
https://github.com/vim/vim/commit/78954f86c2027c766d9e2b5f7904b5fb4041d250
Author: Aaron Burrow <[email protected]>
Date: Mon Apr 6 12:46:40 2026 +0000
patch 9.2.0306: runtime(tar): some issues with lz4 support
Problem: runtime(tar): some issues with lz4 support
Solution: Fix bugs (see below) (Aaron Burrow)
The tar plugin allows users to extract files from tar archives that are
compressed with lz4. But, tar#Extract() builds malformed extraction commands
for lz4-compressed tar archives. This commit fixes three issues in that
code.
The first affects archives with a .tlz4 extension and the other two affect
archives with .tar.lz4 extension (but one of these is symmetric to the issue
that .tlz4 archives had).
(1) When trying to extract .tlz4 archives the command created by
tar#Extract looked like this:
tar -I lz4pxf foo.tlz4 foo
This isn't right. It should be something like this:
tar -I lz4 -pxf foo.tlz4 foo
This was happening because tar.plugin is just substituting on the
first - in "tar -pxf". This works fine if we just add a simple flag for
extraction (eg, z for .tgz), but for lz4 we need to add "-I lz4".
I don't believe that there is an obvious good way to fix this without
reworking the way the command is generated. Probably we should collect
the command and flags separately and the flags should be stored in a
set. Then put everything together into a string just before issuing it
as an extraction command. Unfortunately, this might break things for users
because they have access to tar_extractcmd.
This patch just makes the substitution a little bit more clever so that it
does the right thing when substituting on a string like "tar -pxf".
(2) .tar.lz4 extractions had the same issue, which my patch fixes in
the same way.
(3) .tar.lz4 extractions had another issue. There was a space missing
in the command generated by tar#Extract. This meant that commands
looked like this (notice the lack of space between the archive and output
file names):
tar -I lz4pxf foo.tar.lz4foo
This patch just puts a space where it should be.
Finally, I should note that ChatGPT 5.4 initially identified this issue
in the code and generated the test cases. I reviewed the test cases,
wrote the patch, and actually ran vim against the tests (both with and
without the patch).
closes: #19925
Signed-off-by: Aaron Burrow <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim
index 73829a2d5..110327e95 100644
--- a/runtime/autoload/tar.vim
+++ b/runtime/autoload/tar.vim
@@ -20,6 +20,7 @@
" 2025 Jul 16 by Vim Project: update minimum vim version
" 2026 Feb 06 by Vim Project: consider 'nowrapscan' (#19333)
" 2026 Feb 07 by Vim Project: make the path traversal detection more robust
(#19341)
+" 2026 Apr 06 by Vim Project: fix bugs with lz4 support (#19925)
"
" Contains many ideas from Michael Toren's <tar.vim>
"
@@ -704,7 +705,9 @@ fun! tar#Extract()
endif
elseif filereadable(tarbase.".tlz4")
- let extractcmd= substitute(extractcmd,"-","-I lz4","")
+ if has("linux")
+ let extractcmd= substitute(extractcmd,"-","-I lz4 -","")
+ endif
call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
if v:shell_error != 0
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}:
failed!")
@@ -713,8 +716,10 @@ fun! tar#Extract()
endif
elseif filereadable(tarbase.".tar.lz4")
- let extractcmd= substitute(extractcmd,"-","-I lz4","")
- call system(extractcmd."
".shellescape(tarbase).".tar.lz4".shellescape(fname))
+ if has("linux")
+ let extractcmd= substitute(extractcmd,"-","-I lz4 -","")
+ endif
+ call system(extractcmd." ".shellescape(tarbase).".tar.lz4
".shellescape(fname))
if v:shell_error != 0
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4
{fname}: failed!")
else
diff --git a/src/testdir/test_plugin_tar.vim b/src/testdir/test_plugin_tar.vim
index 8d34ce11a..d6dbdd761 100644
--- a/src/testdir/test_plugin_tar.vim
+++ b/src/testdir/test_plugin_tar.vim
@@ -147,3 +147,57 @@ def g:Test_tar_path_traversal_with_nowrapscan()
bw!
enddef
+
+def g:Test_tar_lz4_extract()
+ CheckExecutable lz4
+
+ delete('X.txt')
+ delete('Xarchive.tar')
+ delete('Xarchive.tar.lz4')
+ call writefile(['hello'], 'X.txt')
+ call system('tar -cf Xarchive.tar X.txt')
+ assert_equal(0, v:shell_error)
+
+ call system('lz4 -z Xarchive.tar Xarchive.tar.lz4')
+ assert_equal(0, v:shell_error)
+
+ delete('X.txt')
+ delete('Xarchive.tar')
+ defer delete('Xarchive.tar.lz4')
+
+ e Xarchive.tar.lz4
+ assert_match('X.txt', getline(5))
+ :5
+ normal x
+ assert_true(filereadable('X.txt'))
+ assert_equal(['hello'], readfile('X.txt'))
+ delete('X.txt')
+ bw!
+enddef
+
+def g:Test_tlz4_extract()
+ CheckExecutable lz4
+
+ delete('X.txt')
+ delete('Xarchive.tar')
+ delete('Xarchive.tlz4')
+ call writefile(['goodbye'], 'X.txt')
+ call system('tar -cf Xarchive.tar X.txt')
+ assert_equal(0, v:shell_error)
+
+ call system('lz4 -z Xarchive.tar Xarchive.tlz4')
+ assert_equal(0, v:shell_error)
+
+ delete('X.txt')
+ delete('Xarchive.tar')
+ defer delete('Xarchive.tlz4')
+
+ e Xarchive.tlz4
+ assert_match('X.txt', getline(5))
+ :5
+ normal x
+ assert_true(filereadable('X.txt'))
+ assert_equal(['goodbye'], readfile('X.txt'))
+ delete('X.txt')
+ bw!
+enddef
diff --git a/src/version.c b/src/version.c
index 6ef0b3864..a149bba0a 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 */
+/**/
+ 306,
/**/
305,
/**/
--
--
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/E1w9jYi-006qm7-9d%40256bit.org.