JuliaIO / Tar.jl

TAR files: create, list, extract them in pure Julia
MIT License
80 stars 19 forks source link

Tar.jl doesn't workaround absolute paths, but `tar -xf` works #154

Closed Dale-Black closed 1 year ago

Dale-Black commented 1 year ago

Not sure I understand this, so I don't know how to adequately describe what's going on, but tar -xf works, whereas Tar.jl doesn't. Here is a recent discussion on Slack I posted

How do you use Tar.extract? Seems like this should be easy, but this example code:

example_tar_path = "path/to/tar"
example_tar_file = "file.tar"
example_output_dir = "path/to/output"
Tar.extract(joinpath(example_tar_path, example_tar_file), example_output_dir)

Is causing an error:

path is absolute

Tar.Header("/images/MESASWEEROM_MESA3010171_20010307_153121/", :directory, 0o40775, 0, "")

error(::String)@error.jl:35
check_header(::Tar.Header)@header.jl:134
var"#read_tarball#47"(::Vector{UInt8}, ::Base.DevNull, ::typeof(Tar.read_tarball), ::Tar.var"#26#28"{Vector{UInt8}, Bool, Bool, IOStream, String}, ::Tar.var"#1#2", ::IOStream)@extract.jl:390
var"#extract_tarball#25"(::Vector{UInt8}, ::Base.DevNull, ::Bool, ::Bool, ::typeof(Tar.extract_tarball), ::Function, ::IOStream, ::String)@extract.jl:58
(::Tar.var"#85#88"{String, IOStream, Bool, Tar.var"#1#2"})(::Base.DevNull)@Tar.jl:237
arg_write(::Tar.var"#85#88"{String, IOStream, Bool, Tar.var"#1#2"}, ::Base.DevNull)@ArgTools.jl:134
#84@Tar.jl:236[inlined]
arg_mkdir(::Tar.var"#84#87"{IOStream, Base.DevNull, Bool, Tar.var"#1#2"}, ::String)@ArgTools.jl:185
#83@Tar.jl:232[inlined]
var"#open#378"(::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:lock,), Tuple{Bool}}}, ::typeof(open), ::Tar.var"#83#86"{Base.DevNull, Bool, Tar.var"#1#2", String}, ::String)@io.jl:384
#open_nolock#1@ArgTools.jl:35[inlined]
open_nolock@ArgTools.jl:35[inlined]
arg_read@ArgTools.jl:74[inlined]
var"#extract#82"(::Nothing, ::Nothing, ::Bool, ::typeof(Tar.extract), ::Function, ::String, ::String)@Tar.jl:231
#extract#89@Tar.jl:255[inlined]
extract(::String, ::String)@Tar.jl:248
top-level scope@Local: 29[inlined]

Currently a simple workaround is:

input_path = joinpath(example_tar_path, example_tar_file)
command = `tar -xf $input_path`
cd(example_output_dir) do
    run(command)
end
Dale-Black commented 1 year ago

And this was a comment from someone who understands this better than me

It's not the path you're passing to Tar.jl, but rather the tar file itself has absolute paths inside of it. E.g. from your error ,/images/MESASWEEROM_MESA3010171_20010307_153121/ is saying the file should be extracted to root ( / ) in a folder called images. I'm assuming tar just ignores the absolute path and extracts to ./images ? You could open an issue here , maybe Tar.jl should do the same

Dale-Black commented 1 year ago

Here are the logs from using tar -xf

tar: Removing leading '/' from member names
tar: Removing leading '/' from member names
tar: Removing leading '/' from member names
tar: Removing leading '/' from member names
StefanKarpinski commented 1 year ago

Not sure there's anything to do here. This tarball has absolute paths in it, which Tar.jl refuses to extract since that would be wildly insecure to allow. The tar command handles this by ignoring the leading /, which makes very little sense to me... like why is that a reasonable thing to do? ./images and /images are not the same thing. So it seems that raising an error is the only reasonable behavior here.

Dale-Black commented 1 year ago

Gotcha, okay thanks for that information.