A relative file:// path is accepted, so the destination moves with the working directory and a backup can exit 0 and be unrestorable #299

Open
opened 2026-10-13 00:47:08 +02:00 by clawbot · 1 comment
Collaborator

Found by the defect hunt in #288 (part 5).

What is wrong: ParseStorageURL (internal/storage/url.go) takes everything after file:// verbatim. storage_url: "file://dest" is accepted and resolved against the working directory, and the local index's destination binding (internal/vaultik/storage_bind.go) compares the raw string, so it never notices the destination moved. The same verbatim handling skips percent-decoding: file:///.../my%20stick/backup creates a new directory literally named my%20stick beside my stick.

How it was shown: with storage_url: "file://dest", snapshot create was run from A/, a file changed, then snapshot create run from B/: both exited 0. The unchanged file's blob exists only under A/dest, so from B/, snapshot verify failed with "1 blobs are missing" and snapshot restore with "object not found".

Definition of done

  • A file:// URL whose path is not absolute is rejected when the config loads, with an error that says to use an absolute path.
  • Percent-escapes in a file:// path are decoded; a path written with a literal space keeps working.
  • Tests cover a relative path, a percent-escaped path and a path with a space.

Model: opus-5-5

Found by the defect hunt in https://git.eeqj.de/sneak/vaultik/issues/288 (part 5). **What is wrong:** `ParseStorageURL` (`internal/storage/url.go`) takes everything after `file://` verbatim. `storage_url: "file://dest"` is accepted and resolved against the working directory, and the local index's destination binding (`internal/vaultik/storage_bind.go`) compares the raw string, so it never notices the destination moved. The same verbatim handling skips percent-decoding: `file:///.../my%20stick/backup` creates a new directory literally named `my%20stick` beside `my stick`. **How it was shown:** with `storage_url: "file://dest"`, `snapshot create` was run from `A/`, a file changed, then `snapshot create` run from `B/`: both exited 0. The unchanged file's blob exists only under `A/dest`, so from `B/`, `snapshot verify` failed with "1 blobs are missing" and `snapshot restore` with "object not found". **Definition of done** - A `file://` URL whose path is not absolute is rejected when the config loads, with an error that says to use an absolute path. - Percent-escapes in a `file://` path are decoded; a path written with a literal space keeps working. - Tests cover a relative path, a percent-escaped path and a path with a space. Model: opus-5-5
clawbot added the critical label 2026-10-13 00:47:08 +02:00
clawbot self-assigned this 2026-10-13 00:47:08 +02:00
Author
Collaborator

Built in #330: loading the config now refuses a file:// storage_url whose path is not absolute, with an error asking for an absolute path, and percent-escapes in a file:// path are decoded, while a literal space still works. One judgement call is noted in the PR: a % not followed by two hex digits is now an error.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/vaultik/pulls/330: loading the config now refuses a `file://` `storage_url` whose path is not absolute, with an error asking for an absolute path, and percent-escapes in a `file://` path are decoded, while a literal space still works. One judgement call is noted in the PR: a `%` not followed by two hex digits is now an error. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/vaultik#299