Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add set_permissions argument #113

Merged
merged 8 commits into from
Jun 8, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,12 @@ recreated. The `skeleton` and `predicate` arguments cannot be used together.
extract([ predicate, ] tarball, [ dir ];
[ skeleton, ] [ copy_symlinks ]) -> dir
```
* `predicate :: Header --> Bool`
* `tarball :: Union{AbstractString, AbstractCmd, IO}`
* `dir :: AbstractString`
* `skeleton :: Union{AbstractString, AbstractCmd, IO}`
* `copy_symlinks :: Bool`
* `predicate :: Header --> Bool`
* `tarball :: Union{AbstractString, AbstractCmd, IO}`
* `dir :: AbstractString`
* `skeleton :: Union{AbstractString, AbstractCmd, IO}`
* `copy_symlinks :: Bool`
* `set_permissions :: Bool`

Extract a tar archive ("tarball") located at the path `tarball` into the
directory `dir`. If `tarball` is an IO object instead of a path, then the
Expand Down Expand Up @@ -105,6 +106,8 @@ will also not be copied and will instead be skipped. By default, `extract` will
detect whether symlinks can be created in `dir` or not and will automatically
copy symlinks if they cannot be created.

If `set_permissions` is `false`, no permissions are set on the extracted files.

### Tar.list

```jl
Expand Down
20 changes: 14 additions & 6 deletions src/Tar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,15 @@ end

"""
extract([ predicate, ] tarball, [ dir ];
[ skeleton, ] [ copy_symlinks ]) -> dir
[ skeleton, ] [ copy_symlinks ],
[ set_permissions ]) -> dir

predicate :: Header --> Bool
tarball :: Union{AbstractString, AbstractCmd, IO}
dir :: AbstractString
skeleton :: Union{AbstractString, AbstractCmd, IO}
copy_symlinks :: Bool
predicate :: Header --> Bool
tarball :: Union{AbstractString, AbstractCmd, IO}
dir :: AbstractString
skeleton :: Union{AbstractString, AbstractCmd, IO}
copy_symlinks :: Bool
set_permissions :: Bool

Extract a tar archive ("tarball") located at the path `tarball` into the
directory `dir`. If `tarball` is an IO object instead of a path, then the
Expand Down Expand Up @@ -207,13 +209,16 @@ link to `/etc/passwd` will not be copied. Symlinks which are in any way cyclic
will also not be copied and will instead be skipped. By default, `extract` will
detect whether symlinks can be created in `dir` or not and will automatically
copy symlinks if they cannot be created.

If `set_permissions` is `false`, no permissions are set on the extracted files.
"""
function extract(
predicate::Function,
tarball::ArgRead,
dir::Union{AbstractString, Nothing} = nothing;
skeleton::Union{ArgWrite, Nothing} = nothing,
copy_symlinks::Union{Bool, Nothing} = nothing,
set_permissions::Bool = true,
)
predicate === true_predicate || skeleton === nothing ||
error("extract: predicate and skeleton cannot be used together")
Expand All @@ -230,6 +235,7 @@ function extract(
predicate, tar, dir,
skeleton = skeleton,
copy_symlinks = copy_symlinks,
set_permissions = set_permissions,
)
end
end
Expand All @@ -241,11 +247,13 @@ function extract(
dir::Union{AbstractString, Nothing} = nothing;
skeleton::Union{ArgWrite, Nothing} = nothing,
copy_symlinks::Union{Bool, Nothing} = nothing,
set_permissions::Bool = true,
)
extract(
true_predicate, tarball, dir,
skeleton = skeleton,
copy_symlinks = copy_symlinks,
set_permissions = set_permissions
StefanKarpinski marked this conversation as resolved.
Show resolved Hide resolved
)
end

Expand Down
5 changes: 3 additions & 2 deletions src/extract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function extract_tarball(
buf::Vector{UInt8} = Vector{UInt8}(undef, DEFAULT_BUFFER_SIZE),
skeleton::IO = devnull,
copy_symlinks::Bool = false,
set_permissions::Bool = true,
)
paths = read_tarball(predicate, tar; buf=buf, skeleton=skeleton) do hdr, parts
# get the file system version of the path
Expand Down Expand Up @@ -82,7 +83,7 @@ function extract_tarball(
error("unsupported tarball entry type: $(hdr.type)")
end
# apply tarball permissions
if hdr.type in (:file, :hardlink)
if set_permissions && hdr.type in (:file, :hardlink)
exec = 0o100 & hdr.mode != 0
tar_mode = exec ? 0o755 : 0o644
sys_mode = filemode(sys_path)
Expand Down Expand Up @@ -139,7 +140,7 @@ function extract_tarball(
src = reduce(joinpath, init=root, split(what, '/'))
dst = reduce(joinpath, init=root, split(path, '/'))
cp(src, dst)
if Sys.iswindows()
if set_permissions && Sys.iswindows()
# our `cp` doesn't copy ACL properties, so manually set them via `chmod`
function copy_mode(src::String, dst::String)
chmod(dst, filemode(src))
Expand Down
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -861,5 +861,14 @@ if Sys.iswindows() && Sys.which("icacls") !== nothing && VERSION >= v"1.6"
x_acl = readchomp(`icacls $(x_path)`)
@test occursin("Everyone:(RX,WA)", x_acl)
end

mktempdir() do dir
Tar.extract(tarball, dir, set_permissions=false)
f_path = joinpath(dir, "0-ffffffff")
@test isfile(f_path)
StefanKarpinski marked this conversation as resolved.
Show resolved Hide resolved

x_path = joinpath(dir, "0-xxxxxxxx")
@test isfile(x_path)
end
StefanKarpinski marked this conversation as resolved.
Show resolved Hide resolved
end
end