openDB (db.go) builds the SQLite connection string as "file:" + path + "?_pragma=..." with the path unescaped. The driver
treats the first ? as the start of the options and # as a
fragment, so a database path containing ?, # or % — legal in a
Unix path, and the path comes straight from SFDUPES_DATABASE — opens
a different file than the one named, silently. scan then creates and
fills a database at the truncated path while reporting success against
the requested one.
Definition of done
The path is escaped when the connection string is built (a net/urlURL{Scheme: "file", Path: ...} or equivalent standard
library call; nothing hand-rolled), so every byte of the path
reaches SQLite as part of the file name.
A test runs scan then report with SFDUPES_DATABASE pointing
at a file whose name contains ?, #, % and a space, and
asserts that exactly that file exists afterwards and no truncated
sibling does.
Relative database paths keep working.
make check green.
Touches db.go; sequence after #8, which rewrites the same
function.
Model: fable-5-1
`openDB` (`db.go`) builds the SQLite connection string as
`"file:" + path + "?_pragma=..."` with the path unescaped. The driver
treats the first `?` as the start of the options and `#` as a
fragment, so a database path containing `?`, `#` or `%` — legal in a
Unix path, and the path comes straight from `SFDUPES_DATABASE` — opens
a different file than the one named, silently. `scan` then creates and
fills a database at the truncated path while reporting success against
the requested one.
## Definition of done
1. The path is escaped when the connection string is built (a
`net/url` `URL{Scheme: "file", Path: ...}` or equivalent standard
library call; nothing hand-rolled), so every byte of the path
reaches SQLite as part of the file name.
2. A test runs `scan` then `report` with `SFDUPES_DATABASE` pointing
at a file whose name contains `?`, `#`, `%` and a space, and
asserts that exactly that file exists afterwards and no truncated
sibling does.
3. Relative database paths keep working.
4. `make check` green.
Touches `db.go`; sequence after
https://git.eeqj.de/sneak/sfdupes/issues/8, which rewrites the same
function.
Model: fable-5-1
clawbot
added this to the 1.0.0 milestone 2026-09-21 09:17:54 +02:00
Plan (implementer's brief). There are now two connection strings, the read-write one for scan and the read-only one for report and trees (#8); both must escape the path the same way, through one standard-library call (net/url), not a hand-rolled escape. The test runs scan then report and trees against a database path holding ?, #, % and a space, and checks that exactly that file exists, along with its lock file (<path>.lock, #53), and no truncated sibling.
Model: opus-5-5
Plan (implementer's brief). There are now two connection strings, the read-write one for `scan` and the read-only one for `report` and `trees` (https://git.eeqj.de/sneak/sfdupes/issues/8); both must escape the path the same way, through one standard-library call (`net/url`), not a hand-rolled escape. The test runs `scan` then `report` and `trees` against a database path holding `?`, `#`, `%` and a space, and checks that exactly that file exists, along with its lock file (`<path>.lock`, https://git.eeqj.de/sneak/sfdupes/issues/53), and no truncated sibling.
Model: opus-5-5
clawbot
self-assigned this 2026-10-04 12:02:37 +02:00
Implemented in #87: the database path is escaped through net/url in the one place both connection strings are built, without cleaning it, and a test covers an absolute path, a path starting with // and a relative path.
Model: opus-5-5
Implemented in https://git.eeqj.de/sneak/sfdupes/pulls/87: the database path is escaped through `net/url` in the one place both connection strings are built, without cleaning it, and a test covers an absolute path, a path starting with `//` and a relative path.
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.
openDB(db.go) builds the SQLite connection string as"file:" + path + "?_pragma=..."with the path unescaped. The drivertreats the first
?as the start of the options and#as afragment, so a database path containing
?,#or%— legal in aUnix path, and the path comes straight from
SFDUPES_DATABASE— opensa different file than the one named, silently.
scanthen creates andfills a database at the truncated path while reporting success against
the requested one.
Definition of done
net/urlURL{Scheme: "file", Path: ...}or equivalent standardlibrary call; nothing hand-rolled), so every byte of the path
reaches SQLite as part of the file name.
scanthenreportwithSFDUPES_DATABASEpointingat a file whose name contains
?,#,%and a space, andasserts that exactly that file exists afterwards and no truncated
sibling does.
make checkgreen.Touches
db.go; sequence after#8, which rewrites the same
function.
Model: fable-5-1
Plan (implementer's brief). There are now two connection strings, the read-write one for
scanand the read-only one forreportandtrees(#8); both must escape the path the same way, through one standard-library call (net/url), not a hand-rolled escape. The test runsscanthenreportandtreesagainst a database path holding?,#,%and a space, and checks that exactly that file exists, along with its lock file (<path>.lock, #53), and no truncated sibling.Model: opus-5-5
Implemented in #87: the database path is escaped through
net/urlin the one place both connection strings are built, without cleaning it, and a test covers an absolute path, a path starting with//and a relative path.Model: opus-5-5