Skip to content

Commit 78954f8

Browse files
7188ce06chrisbra
authored andcommitted
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]>
1 parent 48581f2 commit 78954f8

3 files changed

Lines changed: 64 additions & 3 deletions

File tree

runtime/autoload/tar.vim

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
" 2025 Jul 16 by Vim Project: update minimum vim version
2121
" 2026 Feb 06 by Vim Project: consider 'nowrapscan' (#19333)
2222
" 2026 Feb 07 by Vim Project: make the path traversal detection more robust (#19341)
23+
" 2026 Apr 06 by Vim Project: fix bugs with lz4 support (#19925)
2324
"
2425
" Contains many ideas from Michael Toren's <tar.vim>
2526
"
@@ -704,7 +705,9 @@ fun! tar#Extract()
704705
endif
705706

706707
elseif filereadable(tarbase.".tlz4")
707-
let extractcmd= substitute(extractcmd,"-","-I lz4","")
708+
if has("linux")
709+
let extractcmd= substitute(extractcmd,"-","-I lz4 -","")
710+
endif
708711
call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
709712
if v:shell_error != 0
710713
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}: failed!")
@@ -713,8 +716,10 @@ fun! tar#Extract()
713716
endif
714717

715718
elseif filereadable(tarbase.".tar.lz4")
716-
let extractcmd= substitute(extractcmd,"-","-I lz4","")
717-
call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
719+
if has("linux")
720+
let extractcmd= substitute(extractcmd,"-","-I lz4 -","")
721+
endif
722+
call system(extractcmd." ".shellescape(tarbase).".tar.lz4 ".shellescape(fname))
718723
if v:shell_error != 0
719724
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4 {fname}: failed!")
720725
else

src/testdir/test_plugin_tar.vim

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,57 @@ def g:Test_tar_path_traversal_with_nowrapscan()
147147

148148
bw!
149149
enddef
150+
151+
def g:Test_tar_lz4_extract()
152+
CheckExecutable lz4
153+
154+
delete('X.txt')
155+
delete('Xarchive.tar')
156+
delete('Xarchive.tar.lz4')
157+
call writefile(['hello'], 'X.txt')
158+
call system('tar -cf Xarchive.tar X.txt')
159+
assert_equal(0, v:shell_error)
160+
161+
call system('lz4 -z Xarchive.tar Xarchive.tar.lz4')
162+
assert_equal(0, v:shell_error)
163+
164+
delete('X.txt')
165+
delete('Xarchive.tar')
166+
defer delete('Xarchive.tar.lz4')
167+
168+
e Xarchive.tar.lz4
169+
assert_match('X.txt', getline(5))
170+
:5
171+
normal x
172+
assert_true(filereadable('X.txt'))
173+
assert_equal(['hello'], readfile('X.txt'))
174+
delete('X.txt')
175+
bw!
176+
enddef
177+
178+
def g:Test_tlz4_extract()
179+
CheckExecutable lz4
180+
181+
delete('X.txt')
182+
delete('Xarchive.tar')
183+
delete('Xarchive.tlz4')
184+
call writefile(['goodbye'], 'X.txt')
185+
call system('tar -cf Xarchive.tar X.txt')
186+
assert_equal(0, v:shell_error)
187+
188+
call system('lz4 -z Xarchive.tar Xarchive.tlz4')
189+
assert_equal(0, v:shell_error)
190+
191+
delete('X.txt')
192+
delete('Xarchive.tar')
193+
defer delete('Xarchive.tlz4')
194+
195+
e Xarchive.tlz4
196+
assert_match('X.txt', getline(5))
197+
:5
198+
normal x
199+
assert_true(filereadable('X.txt'))
200+
assert_equal(['goodbye'], readfile('X.txt'))
201+
delete('X.txt')
202+
bw!
203+
enddef

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
306,
737739
/**/
738740
305,
739741
/**/

0 commit comments

Comments
 (0)