README "Database" says SFDUPES_DATABASE names the database file exactly. scan opens the file through that exact path, but it creates the missing parent folder from filepath.Dir(path) in lockScanDatabase and openScanDatabase (db.go). filepath.Dir cleans the path as text, dropping each .. together with the name before it without checking for a symlink. With SFDUPES_DATABASE=/srv/link/../new/db.sqlite, /srv/link pointing to /data/x and /data/new missing, scan creates /srv/new. The path itself leads to /data/new, so scan then fails to create the database there, leaving an empty /srv/new behind.
Definition of done
scan creates the folder the database path actually leads to: the path with its last element removed as plain text, never cleaned, so .. is followed through symlinks as the system follows it when opening the file.
Both places that create the folder use the same helper, in db.go beside databasePath.
Tests: the case above, a symlinked directory followed by .. and a missing folder. The database lands where the path leads, and nothing is created at the cleaned path. Plus a plain missing folder, as now.
TODO.md Completed Steps entry in the same commit; script/cibuild green on a fresh clone.
Notes for the implementer
Package main (the repo's only package); db.go only, plus its tests.
Small and plain.
Model: opus-5-5
Found while reworking https://git.eeqj.de/sneak/sfdupes/pulls/118 for https://git.eeqj.de/sneak/sfdupes/issues/111.
README "Database" says `SFDUPES_DATABASE` names the database file exactly. `scan` opens the file through that exact path, but it creates the missing parent folder from `filepath.Dir(path)` in `lockScanDatabase` and `openScanDatabase` (`db.go`). `filepath.Dir` cleans the path as text, dropping each `..` together with the name before it without checking for a symlink. With `SFDUPES_DATABASE=/srv/link/../new/db.sqlite`, `/srv/link` pointing to `/data/x` and `/data/new` missing, `scan` creates `/srv/new`. The path itself leads to `/data/new`, so `scan` then fails to create the database there, leaving an empty `/srv/new` behind.
## Definition of done
- `scan` creates the folder the database path actually leads to: the path with its last element removed as plain text, never cleaned, so `..` is followed through symlinks as the system follows it when opening the file.
- Both places that create the folder use the same helper, in `db.go` beside `databasePath`.
- Tests: the case above, a symlinked directory followed by `..` and a missing folder. The database lands where the path leads, and nothing is created at the cleaned path. Plus a plain missing folder, as now.
- `TODO.md` Completed Steps entry in the same commit; `script/cibuild` green on a fresh clone.
## Notes for the implementer
- Package `main` (the repo's only package); `db.go` only, plus its tests.
- Small and plain.
Model: opus-5-5
clawbot
added this to the 1.0.0 milestone 2026-10-16 14:45:15 +02:00
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 while reworking #118 for #111.
README "Database" says
SFDUPES_DATABASEnames the database file exactly.scanopens the file through that exact path, but it creates the missing parent folder fromfilepath.Dir(path)inlockScanDatabaseandopenScanDatabase(db.go).filepath.Dircleans the path as text, dropping each..together with the name before it without checking for a symlink. WithSFDUPES_DATABASE=/srv/link/../new/db.sqlite,/srv/linkpointing to/data/xand/data/newmissing,scancreates/srv/new. The path itself leads to/data/new, soscanthen fails to create the database there, leaving an empty/srv/newbehind.Definition of done
scancreates the folder the database path actually leads to: the path with its last element removed as plain text, never cleaned, so..is followed through symlinks as the system follows it when opening the file.db.gobesidedatabasePath...and a missing folder. The database lands where the path leads, and nothing is created at the cleaned path. Plus a plain missing folder, as now.TODO.mdCompleted Steps entry in the same commit;script/cibuildgreen on a fresh clone.Notes for the implementer
main(the repo's only package);db.goonly, plus its tests.Model: opus-5-5