SQLiteDSN in internal/database/sqlite_open.go builds file: + path + ? + parameters without escaping the path. SQLite reads a file: URI's path only up to the first ? or #, and decodes % escapes in it. With DATA_DIR=/srv/hooks#1, webhooker.db and every events-{uuid}.db open as one file, /srv/hooks, and the mode parameter after the # is dropped.
It showed up in a test: Go names a repeated subtest name#01, and t.TempDir() puts that in the path.
Done when a data directory whose path holds #, ? or % gives each database its own file at the path asked for, with a test that opens databases there.
Model: opus-5-5
`SQLiteDSN` in `internal/database/sqlite_open.go` builds `file:` + path + `?` + parameters without escaping the path. SQLite reads a `file:` URI's path only up to the first `?` or `#`, and decodes `%` escapes in it. With `DATA_DIR=/srv/hooks#1`, `webhooker.db` and every `events-{uuid}.db` open as one file, `/srv/hooks`, and the `mode` parameter after the `#` is dropped.
It showed up in a test: Go names a repeated subtest `name#01`, and `t.TempDir()` puts that in the path.
Done when a data directory whose path holds `#`, `?` or `%` gives each database its own file at the path asked for, with a test that opens databases there.
Model: opus-5-5
Plan: escape the path in SQLiteDSN (internal/database/sqlite_open.go) so SQLite reads it back exactly: at least %, ? and #, using the standard library's URL escaping rather than hand-written replacements. Every database file is opened through it, so the main database, the event databases and the archive files are all covered by the one change.
Test: a data directory whose path holds #, ? and % gets each database at its own file at the path asked for (the files exist under that directory, and two different databases do not share one).
Model: opus-5-5
Plan: escape the path in `SQLiteDSN` (`internal/database/sqlite_open.go`) so SQLite reads it back exactly: at least `%`, `?` and `#`, using the standard library's URL escaping rather than hand-written replacements. Every database file is opened through it, so the main database, the event databases and the archive files are all covered by the one change.
Test: a data directory whose path holds `#`, `?` and `%` gets each database at its own file at the path asked for (the files exist under that directory, and two different databases do not share one).
Model: opus-5-5
clawbot
self-assigned this 2026-10-13 05:32:20 +02:00
Fixed in #523: the connection string is now built with url.URL, so #, ? and % in the data directory path reach SQLite escaped and each database opens its own file.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/webhooker/pulls/523: the connection string is now built with `url.URL`, so `#`, `?` and `%` in the data directory path reach SQLite escaped and each database opens its own file.
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.
SQLiteDSNininternal/database/sqlite_open.gobuildsfile:+ path +?+ parameters without escaping the path. SQLite reads afile:URI's path only up to the first?or#, and decodes%escapes in it. WithDATA_DIR=/srv/hooks#1,webhooker.dband everyevents-{uuid}.dbopen as one file,/srv/hooks, and themodeparameter after the#is dropped.It showed up in a test: Go names a repeated subtest
name#01, andt.TempDir()puts that in the path.Done when a data directory whose path holds
#,?or%gives each database its own file at the path asked for, with a test that opens databases there.Model: opus-5-5
Plan: escape the path in
SQLiteDSN(internal/database/sqlite_open.go) so SQLite reads it back exactly: at least%,?and#, using the standard library's URL escaping rather than hand-written replacements. Every database file is opened through it, so the main database, the event databases and the archive files are all covered by the one change.Test: a data directory whose path holds
#,?and%gets each database at its own file at the path asked for (the files exist under that directory, and two different databases do not share one).Model: opus-5-5
Fixed in #523: the connection string is now built with
url.URL, so#,?and%in the data directory path reach SQLite escaped and each database opens its own file.Model: opus-5-5