Skip to content

match ./-prefixed archive entries in extract_file - #211

Merged
jaemk merged 1 commit into
masterfrom
260901.archive-dot-slash
Sep 2, 2026
Merged

jaemk merged 1 commit into
masterfrom
260901.archive-dot-slash

Conversation

@jaemk

@jaemk jaemk commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Fixes the ./-prefixed archive entry lookup reported in #27, and pins the github asset-URL
contract #77 was about.

  • Match ./-prefixed entries in Extract::extract_file on both the tar and zip arms, through a
    shared archive_path_matches. tar -czf app.tar.gz -C dir . stores every entry as ./name, so
    such an archive failed with "Could not find the required path in the archive" even though the
    file was present. A ./-prefixed bin_path_in_archive now also matches a plainly-named entry.
  • Compare interior components exactly, so a same-named file in a subdirectory cannot be selected
    by accident (archive_path_matching_ignores_only_a_leading_dot_slash).
  • Add tests for both directions on tar and zip, built from archives that really store the
    ./ prefix (append_data normalizes it away, so the raw GNU header name is set directly).
  • Pin that a nested zip tree with no directory entries is restored recursively (Fix recursive zip extraction. #20).
  • Pin the github asset download URL as the API url field, not browser_download_url, and the
    download request's Accept: application/octet-stream. Together those are what make a private
    release asset reachable, and neither had coverage (Parse Github Asset Based on Accessibility #77).

make ci is green.

`tar -czf app.tar.gz -C dir .` stores every entry as `./name`, while
`tar -czf app.tar.gz *` stores it as `name`. The lookup in `extract_file` was an exact
path match on both the tar and zip arms, so the first archive failed with "Could not find
the required path in the archive" even though the file was there, and the caller has no
way to know which invocation produced the release artifact.

Both arms now compare through `archive_path_matches`, which ignores a leading `./` on
either side, so a `./`-prefixed request also matches a plainly-named entry. Interior
components are compared exactly, so a same-named file in a subdirectory cannot be selected
by accident.

Reported in #27.

Also pins two contracts that had no coverage: the github asset download URL comes from the
API `url` field (not `browser_download_url`), and the download request carries
`Accept: application/octet-stream`. Together those are what make a private release asset
reachable, and a flip between the two URL fields has broken downloads before (#77).
@jaemk
jaemk force-pushed the 260901.archive-dot-slash branch from 9a18f30 to c2fa13e Compare September 2, 2026 00:46
@jaemk
jaemk merged commit 9558822 into master Sep 2, 2026
4 checks passed
@jaemk
jaemk deleted the 260901.archive-dot-slash branch September 2, 2026 00:50
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.

1 participant