Skip to content

extract: set directory permissions after their contents, so read-only directories extract - #411

Merged
sylvestre merged 2 commits into
uutils:mainfrom
jayhemnani9910:extract-directories-last
Oct 22, 2026
Merged

sylvestre merged 2 commits into
uutils:mainfrom
jayhemnani9910:extract-directories-last

Conversation

@jayhemnani9910

Copy link
Copy Markdown
Contributor

An archive with a read-only directory can't be extracted: the directory is created with its archived mode before the files inside it, so writing them fails.

$ tar -tvf locked.tar
dr-xr-xr-x po/po             0 2026-10-22 00:39 locked/
-rw-rw-r-- po/po             2 2026-10-22 00:39 locked/f
$ tar -xf locked.tar
tar: Cannot extract 'locked/f': failed to unpack `./locked/f`
tar: Error is not recoverable: exiting now           (exit 2; GNU tar 1.35 extracts both)

Directory members are now unpacked after all other members, children before parents, the way tar-rs's own Archive::unpack does it. A file still creates its parent directory when it needs one. A directory member with a .. component is reported where it appears, as before. Directory entries are kept until the end of the archive, like Archive::unpack.

New test test_extract_read_only_directory fails without the change. cargo test --workspace: 110 passed, clippy and fmt clean. The read-only case also works through gzip, zstd and -f -.

Copilot AI balanced review requested due to automatic review settings October 22, 2026 05:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.55172% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.17%. Comparing base (791ae26) to head (8a0f4ed).
⚠️ Report is 98 commits behind head on main.

Files with missing lines Patch % Lines
src/uu/tar/src/operations/extract.rs 87.50% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #411      +/-   ##
==========================================
+ Coverage   96.84%   98.17%   +1.32%     
==========================================
  Files          11       15       +4     
  Lines        1492     1970     +478     
  Branches       29       39      +10     
==========================================
+ Hits         1445     1934     +489     
+ Misses         46       35      -11     
  Partials        1        1              
Flag Coverage Δ
macos_latest 98.17% <96.55%> (+1.32%) ⬆️
ubuntu_latest 98.17% <96.55%> (+1.32%) ⬆️
windows_latest 0.00% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed

codspeed Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

1 warning

⚠️ 6 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 7 untouched benchmarks


Comparing jayhemnani9910:extract-directories-last (8a0f4ed) with main (94fa386)

Open in CodSpeed

Comment thread src/uu/tar/src/operations/extract.rs Outdated
out.flush().map_err(TarError::Io)?;
report_recoverable(&TarError::MemberNameContainsDotDot { path: path.clone() })?;
refused_member = true;
// A refused `..` member is still reported in archive order

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is a bit cryptic, could you please say that .. directories are not deferred so they are refused in archive order?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8a0f4ed, it now says directories with a .. component are not deferred, so they are refused in archive order.

Comment thread tests/by-util/test_tar.rs
header.set_entry_type(tar_rs_crate::EntryType::Directory);
header.set_mode(0o555);
header.set_size(0);
builder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a nested case too (locked/ and locked/sub/ both 0555 with a file inside)
otherwise the children-before-parents sort isn't tested

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test_extract_nested_read_only_directories in 8a0f4ed: locked/ and locked/sub/ both 0555, with locked/f inside. sub is left empty so nothing else creates it first, and without the children-before-parents sort the test fails with "Cannot extract 'locked/sub/'".

Copilot AI balanced review requested due to automatic review settings October 22, 2026 13:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@sylvestre
sylvestre merged commit b453849 into uutils:main Oct 22, 2026
20 checks passed
@sylvestre

Copy link
Copy Markdown
Contributor

Thanks for your PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants