Path filters match by case-insensitive string prefix: restoring /home/u/doc also restores doc2, Doc3 and doc.txt.bak #223

Closed
opened 2026-10-06 01:49:44 +02:00 by clawbot · 1 comment
Collaborator

FileRepository.ListByPrefix (internal/database/files.go:231-241) selects with path LIKE ? || '%'. That is a plain string prefix, not a path prefix. It is case-insensitive for ASCII, and any _ or % in the argument acts as a wildcard. It has two callers:

  • Restore path arguments (internal/vaultik/restore.go:781-813). Measured on next at 0700901: asking for .../doc/ also restored doc2/b.txt, Doc3/c.txt and doc.txt.bak. Cleaning the filter removes the trailing slash, so the slash does not help. The help text says only matching files and directories are restored.
  • The scanner's known-file load for a backup path (internal/snapshot/scanner.go:425). Files from any other configured path that merely starts with this one are counted as deleted in the backup summary (the comparison is at scanner.go:1913-1927).

Acceptable: a path selects exactly that path and everything beneath it (p itself, or anything starting with p/), compared case-sensitively and with no wildcard characters.

Definition of done

  1. ListByPrefix, renamed if the new meaning calls for it, matches on path boundaries, case-sensitively, with _ and % treated literally. Both callers use it.
  2. Tests cover a sibling with the same leading characters, a different-case sibling, a name containing _ and %, and a directory argument with and without a trailing slash.
  3. make check passes.

Model: fable-5-1 (audit); opus-5-5 (issue)

`FileRepository.ListByPrefix` (`internal/database/files.go:231-241`) selects with `path LIKE ? || '%'`. That is a plain string prefix, not a path prefix. It is case-insensitive for ASCII, and any `_` or `%` in the argument acts as a wildcard. It has two callers: - **Restore path arguments** (`internal/vaultik/restore.go:781-813`). Measured on `next` at `0700901`: asking for `.../doc/` also restored `doc2/b.txt`, `Doc3/c.txt` and `doc.txt.bak`. Cleaning the filter removes the trailing slash, so the slash does not help. The help text says only matching files and directories are restored. - **The scanner's known-file load for a backup path** (`internal/snapshot/scanner.go:425`). Files from any other configured path that merely starts with this one are counted as deleted in the backup summary (the comparison is at `scanner.go:1913-1927`). Acceptable: a path selects exactly that path and everything beneath it (`p` itself, or anything starting with `p/`), compared case-sensitively and with no wildcard characters. ## Definition of done 1. `ListByPrefix`, renamed if the new meaning calls for it, matches on path boundaries, case-sensitively, with `_` and `%` treated literally. Both callers use it. 2. Tests cover a sibling with the same leading characters, a different-case sibling, a name containing `_` and `%`, and a directory argument with and without a trailing slash. 3. `make check` passes. Model: fable-5-1 (audit); opus-5-5 (issue)
clawbot self-assigned this 2026-10-06 01:49:44 +02:00
Author
Collaborator

Reproduced on next at d276d89 with a failing test, then fixed in #250. A path now lists the file at that path and everything beneath it, compared case-sensitively and with _ and % taken literally.

Model: opus-5-5

Reproduced on `next` at `d276d89` with a failing test, then fixed in https://git.eeqj.de/sneak/vaultik/pulls/250. A path now lists the file at that path and everything beneath it, compared case-sensitively and with `_` and `%` taken literally. Model: opus-5-5
Sign in to join this conversation.