What is wrong:parseDuration (internal/vaultik/helpers.go) computes time.Duration(n) * year (and the same for w, mo, d) with no overflow check. From 293y up the product wraps to a negative value, so selectSnapshotsToPurge (internal/vaultik/snapshot.go) puts the cutoff in the future and selects every snapshot. A user who writes --prune --keep-newer-than 1000y to keep everything loses every snapshot of that name, including the one just made, and PruneBlobs then deletes their blobs. The command exits 0.
How it was shown: after two backups, snapshot purge --older-than 1000y listed all four snapshots, including one a second old. 292y lists none; 293y, 15300w and 3600mo list all. snapshot create --cron --prune --keep-newer-than 1000y home exited 0 and left no home snapshot and none of its blobs.
Definition of done
A duration too large to represent (in any unit, and summed over several parts such as 200y200y) is rejected as invalid, with a non-zero exit and nothing deleted, for --keep-newer-than and --older-than alike.
No duration ever selects a snapshot newer than it.
A test covers the overflow for each unit and for a sum of parts.
Model: opus-5-5
Found by the defect hunt in https://git.eeqj.de/sneak/vaultik/issues/288 (part 4).
**What is wrong:** `parseDuration` (`internal/vaultik/helpers.go`) computes `time.Duration(n) * year` (and the same for `w`, `mo`, `d`) with no overflow check. From `293y` up the product wraps to a negative value, so `selectSnapshotsToPurge` (`internal/vaultik/snapshot.go`) puts the cutoff in the future and selects every snapshot. A user who writes `--prune --keep-newer-than 1000y` to keep everything loses every snapshot of that name, including the one just made, and `PruneBlobs` then deletes their blobs. The command exits 0.
**How it was shown:** after two backups, `snapshot purge --older-than 1000y` listed all four snapshots, including one a second old. `292y` lists none; `293y`, `15300w` and `3600mo` list all. `snapshot create --cron --prune --keep-newer-than 1000y home` exited 0 and left no `home` snapshot and none of its blobs.
**Definition of done**
- A duration too large to represent (in any unit, and summed over several parts such as `200y200y`) is rejected as invalid, with a non-zero exit and nothing deleted, for `--keep-newer-than` and `--older-than` alike.
- No duration ever selects a snapshot newer than it.
- A test covers the overflow for each unit and for a sum of parts.
Model: opus-5-5
clawbot
self-assigned this 2026-10-13 00:29:18 +02:00
Fixed in #328: a duration whose total no longer fits in a time.Duration (about 292 years) is now rejected as invalid, so a purge with it stops before anything is deleted.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/vaultik/pulls/328: a duration whose total no longer fits in a `time.Duration` (about 292 years) is now rejected as invalid, so a purge with it stops before anything is deleted.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by the defect hunt in #288 (part 4).
What is wrong:
parseDuration(internal/vaultik/helpers.go) computestime.Duration(n) * year(and the same forw,mo,d) with no overflow check. From293yup the product wraps to a negative value, soselectSnapshotsToPurge(internal/vaultik/snapshot.go) puts the cutoff in the future and selects every snapshot. A user who writes--prune --keep-newer-than 1000yto keep everything loses every snapshot of that name, including the one just made, andPruneBlobsthen deletes their blobs. The command exits 0.How it was shown: after two backups,
snapshot purge --older-than 1000ylisted all four snapshots, including one a second old.292ylists none;293y,15300wand3600molist all.snapshot create --cron --prune --keep-newer-than 1000y homeexited 0 and left nohomesnapshot and none of its blobs.Definition of done
200y200y) is rejected as invalid, with a non-zero exit and nothing deleted, for--keep-newer-thanand--older-thanalike.Model: opus-5-5
Fixed in #328: a duration whose total no longer fits in a
time.Duration(about 292 years) is now rejected as invalid, so a purge with it stops before anything is deleted.Model: opus-5-5