Refuse a relative file:// storage_url and decode its escapes #330

Open
clawbot wants to merge 1 commits from issue-299-file-url-absolute-path into next
Collaborator

Fixes #299.

What was wrong: the path after file:// was used exactly as written. file://dest resolved against the working directory, so a backup run from another directory wrote to a different destination, still exited 0, and left a snapshot that could not be restored. A percent-escape such as my%20stick was not decoded, so it created a new directory with that literal name.

What changed:

  • Loading the config refuses a file:// storage_url whose path is not absolute, with an error that asks for an absolute path, as in file:///path/to/backup.
  • ParseStorageURL refuses the same URL and decodes percent-escapes in the path; a path written with a literal space keeps working.
  • The README's storage backends section states both rules.

Worth knowing:

  • The absolute-path rule is written in both internal/config and internal/storage, because config cannot import storage, which imports config. Both check that a / follows file://.
  • Judgement call: a % not followed by two hex digits (as in .../100%) is now an error, raised when the storage is opened rather than when the config loads. It has to be written %25.
  • file://~/... still works: the tilde is expanded before the check.
  • The local index still records the destination as the raw storage_url text, so switching between the my%20stick and my stick spellings is refused as a different destination. That is the safe direction and is left alone here.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/vaultik/issues/299. **What was wrong:** the path after `file://` was used exactly as written. `file://dest` resolved against the working directory, so a backup run from another directory wrote to a different destination, still exited 0, and left a snapshot that could not be restored. A percent-escape such as `my%20stick` was not decoded, so it created a new directory with that literal name. **What changed:** - Loading the config refuses a `file://` `storage_url` whose path is not absolute, with an error that asks for an absolute path, as in `file:///path/to/backup`. - `ParseStorageURL` refuses the same URL and decodes percent-escapes in the path; a path written with a literal space keeps working. - The README's storage backends section states both rules. **Worth knowing:** - The absolute-path rule is written in both `internal/config` and `internal/storage`, because `config` cannot import `storage`, which imports `config`. Both check that a `/` follows `file://`. - Judgement call: a `%` not followed by two hex digits (as in `.../100%`) is now an error, raised when the storage is opened rather than when the config loads. It has to be written `%25`. - `file://~/...` still works: the tilde is expanded before the check. - The local index still records the destination as the raw `storage_url` text, so switching between the `my%20stick` and `my stick` spellings is refused as a different destination. That is the safe direction and is left alone here. Model: opus-5-5
clawbot self-assigned this 2026-10-13 02:46:37 +02:00
clawbot added the needs-review label 2026-10-13 02:46:42 +02:00
Author
Collaborator

The branch no longer rebases cleanly onto current next: TODO.md conflicts with the Completed Steps entry for #298, which landed at the same spot. Rebase onto next, keep both entries with this one (2026-10-13) on top, and push the single commit again.

Model: opus-5-5

The branch no longer rebases cleanly onto current `next`: `TODO.md` conflicts with the Completed Steps entry for https://git.eeqj.de/sneak/vaultik/issues/298, which landed at the same spot. Rebase onto `next`, keep both entries with this one (2026-10-13) on top, and push the single commit again. Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-10-13 03:55:26 +02:00
clawbot force-pushed issue-299-file-url-absolute-path from f72a71ede0 to d85eabd242 2026-10-13 05:26:29 +02:00 Compare
clawbot added needs-review and removed needs-rebase labels 2026-10-13 05:26:39 +02:00
clawbot added 1 commit 2026-10-13 07:41:28 +02:00
The path after file:// was used as written. file://dest resolved
against the working directory, so a backup run from another directory
wrote elsewhere, exited 0 and left a snapshot that could not be
restored; my%20stick created a directory with that literal name.

Config load now refuses a file:// storage_url whose path is not
absolute. ParseStorageURL refuses it too and decodes percent-escapes;
a literal space still works. The rule is written in both packages
because config cannot import storage, which imports config.

A % not followed by two hex digits now fails when the storage is
opened, not at config load.

Model: opus-5-5
clawbot force-pushed issue-299-file-url-absolute-path from d85eabd242 to 437ec591ad 2026-10-13 07:41:28 +02:00 Compare
Author
Collaborator

Review passed. Needs a rebase (TODO.md only).

Model: opus-5-5

Review passed. Needs a rebase (TODO.md only). Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-10-13 10:27:15 +02:00
Some checks are pending
check / check (push) Waiting to run
This pull request has changes conflicting with the target branch.
  • TODO.md
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-299-file-url-absolute-path:issue-299-file-url-absolute-path
git checkout issue-299-file-url-absolute-path
Sign in to join this conversation.