Skip to content

fix: decompressing with --format overwrites the input file - #1049

Open
VXNCXNX wants to merge 1 commit into
ouch-org:mainfrom
VXNCXNX:fix/format-flag-overwrites-input
Open

fix: decompressing with --format overwrites the input file#1049
VXNCXNX wants to merge 1 commit into
ouch-org:mainfrom
VXNCXNX:fix/format-flag-overwrites-input

Conversation

@VXNCXNX

@VXNCXNX VXNCXNX commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

What's broken

ouch decompress <file> --format <fmt> derives the output name from the input's full file name, so the two are equal. With --here (or --dir .) the input is truncated to zero bytes and the run then fails, so the archive is gone.

Fixes #442

Repro

$ echo "hello world data" > file
$ ouch compress file file.zst.zst.zst
$ ls -l file.zst.zst.zst
44 file.zst.zst.zst

$ ouch decompress file.zst.zst.zst --format zst --here -y
[ERROR] Failed to decompress file.zst.zst.zst
 - incomplete frame
$ ls -l file.zst.zst.zst
0 file.zst.zst.zst        <- input destroyed

after:
[INFO] Input file size: 44 B / Output file size: 35 B
44 file.zst.zst.zst       <- intact, md5 unchanged
35 file.zst.zst           <- output

The fix

Strip as many trailing known extensions as --format names, so file.zst.zst.zst --format zst writes file.zst.zst. A name with no known extension falls back to <name>-output rather than colliding.

Verification

decompress_with_format_flag_does_not_overwrite_input asserts the input bytes are unchanged and the derived output exists. Reverting the name derivation fails it: the input reads back as empty.

I also checked the paths this could have disturbed, comparing binaries built before and after: archive extraction with --format, stdin input, and plain .gz decompression without --format all behave identically.

Full suite passes. cargo fmt --check and cargo clippy --all-targets -- -D warnings clean. I built with bzip3 off, since libbzip3-sys will not compile here (missing stddef.h), and nothing in the diff touches it.

With --format the extensions in the path are not parsed, so the output
name was taken from the input's full file name and the two collided.
With --here or --dir . that truncates the input archive to zero bytes
and then fails, losing the data.

Fixes ouch-org#442
@VXNCXNX
VXNCXNX force-pushed the fix/format-flag-overwrites-input branch from df6dde3 to 2ce08b8 Compare August 25, 2026 16:06
@VXNCXNX

VXNCXNX commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main. The only conflict was CHANGELOG.md, and main has since marked it "This changelog shouldn't be used anymore. This file will be removed soon.", so I dropped my entry rather than re-adding it. CHANGELOG.md here is now identical to main; the diff is code and tests only.

On the new base: cargo test --bins and cargo test --test integration pass, clippy has no errors.

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.

When decompressing with --format, don't overwrite input

1 participant