Repository navigation
Conversation
This was referenced Aug 30, 2026
Collaborator
|
Thanks for this contribution. We're closing outside-contributor pull requests that have had no activity for 14 days or more, so the queue reflects work that can still land. This isn't a judgment on the change itself. If it's still needed, please rebase onto |
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters
ods-backup.sh verify <archive>.tar.gzextracts the full backup intoTMPDIRbefore checking its hashes. The function protected that directory with a BashRETURNtrap, butset -eexits the shell directly whensha256sum -creports a mismatch, so the function never returns and the trap never fires. A damaged archive therefore leaves the entire extracted backup—potentially configuration and user data—on disk after verification fails.The invariant is: archive verification must remove extracted data on every terminal path, including checksum failure.
What changed
EXITcleanup trap inside that subshell, so normal completion andset -efailure both remove the extraction directoryOverlap check
Searched open and closed upstream PRs for backup archive verification, checksum-failure cleanup,
verify_backup, backup temp leaks,RETURNtraps, and changes toods/ods-backup.sh. No PR covers failed archive-verification cleanup. PR #3022 changes only the full-backup model source paths in this file; PR #3066 changes update snapshot publication; PR #3541 confines restore backup IDs. None touches this function or behavior.Regression coverage
tests/test-backup-integrity.shnow drives the publicods-backup.sh ... verify <id>.tar.gzboundary with a real archive whose payload no longer matcheschecksums.sha256, assigns a dedicatedTMPDIR, requires a non-zero verification result, and asserts that no extracted files remain. The assertion fails on upstreammainand passes with this change.Validation
bash tests/test-backup-integrity.sh— passedbash tests/test-backup-restore-roundtrip.sh— passed, including compressed restorebash tests/test-backup-restore-cli.sh— 11 passedbash tests/test-update-rollback-contract.sh— passedbash -n ods/ods-backup.sh tests/test-backup-integrity.sh— passedpre-commit run --files ods/ods-backup.sh ods/tests/test-backup-integrity.sh— passedgit diff --check— passedmakeis unavailable on this Windows host; repository CI remains the full Linux validation gate.Tradeoffs and rollback
The subshell intentionally isolates both the temporary working directory and its
EXITtrap, so it cannot replace a caller trap or change the parent shell's working directory. Rollback simply restores the previousRETURNtrap, but would reintroduce data retention onset -efailures.Combined compatibility validation
Synthetic integration was validated in both relevant merge orders:
175e2fa8: fix(backup): clean extracted data after verification failure #3554 → fix(cli): remove remote-provider secret temp files on failure #3556 → fix(restore): clean invalid archive extraction before retry #3557, then overlapping-file checks with fix(preset): confine names to preset directory #3540, fix(restore): confine backup IDs to backup root #3541, and fix(restore): reject archives whose root doesn't match the backup id #2346492ce800: fix(preset): confine names to preset directory #3540 → fix(cli): remove remote-provider secret temp files on failure #3556 and fix(restore): confine backup IDs to backup root #3541 → fix(restore): reject archives whose root doesn't match the backup id #2346 → fix(restore): clean invalid archive extraction before retry #3557, then fix(backup): clean extracted data after verification failure #3554Both orders merged without conflicts. The combined backup integrity/round-trip/CLI/update rollback, preset confinement, restore-ID confinement, remote-provider CLI contracts, Bash syntax, and
git diff --checkall passed. The three PRs in this batch have no required merge order.