Escape state_dir in the db_url derived from it (closes #290) #292

Merged
clawbot merged 6 commits from issue-290-escape-state-dir-in-db-url into next 2026-10-16 04:37:55 +02:00
3 changed files with 24 additions and 20 deletions
Showing only changes of commit 78fe6957de - Show all commits

No files matched your search

+7 -7
View File
@@ -726,13 +726,13 @@ Key settings in more detail:
- `db_url` — the SQLite database to open; omitted, it is - `db_url` — the SQLite database to open; omitted, it is
`file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the `file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the
database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or
`#` in the name is written as `%25`, `%3F` or `%23`. For a `state_dir` `#` in the name is written as `%25`, `%3F` or `%23`. For a `state_dir` of `/`
starting with `//` it starts `file:////`, so SQLite does not read the first or one starting with `//` it starts `file:////`, so SQLite does not read the
directory name as a host. pixa opens one connection to it, so its own reads first name in the path as a host. pixa opens one connection to it, so its own
and writes run one at a time. pixa adds `_pragma=busy_timeout(5000)` to any reads and writes run one at a time. pixa adds `_pragma=busy_timeout(5000)` to
`db_url`, so a write that finds another program writing to the file waits up any `db_url`, so a write that finds another program writing to the file waits
to five seconds for it instead of failing. WAL mode comes only from the URL: up to five seconds for it instead of failing. WAL mode comes only from the
keep `_pragma=journal_mode(WAL)` in one you set URL: keep `_pragma=journal_mode(WAL)` in one you set
- `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk - `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk
cache entirely; omitted defaults to 75% of the sum of the free space on the cache entirely; omitted defaults to 75% of the sum of the free space on the
filesystem containing `<state_dir>/cache/` and the bytes of source and filesystem containing `<state_dir>/cache/` and the bytes of source and
+8 -8
View File
@@ -30,6 +30,14 @@ P2: security: per-origin rate limiting
# Completed Steps # Completed Steps
- 2026-10-16 a `state_dir` whose name holds `%`, `?` or `#` keeps its database
at `state.sqlite3` in that directory (closes #290): the `db_url` derived from
it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a
`?` or `#` ended the path early, and the journal mode parameter was lost. The
derived `db_url` is now built with Go's `net/url`, which writes those
characters as `%25`, `%3F` and `%23`. For a `state_dir` of `/` or one starting
with `//` it starts `file:////`, so SQLite no longer reads the first name in
the path as a host.
- 2026-10-16 a size with one side `0` keeps the side computed from the source's - 2026-10-16 a size with one side `0` keeps the side computed from the source's
proportions at 1 or more (closes #283): it was rounded down, so for a thin proportions at 1 or more (closes #283): it was rounded down, so for a thin
source it came out at 0, and libvips then made the size square. An 8192x1 source it came out at 0, and libvips then made the size square. An 8192x1
@@ -62,14 +70,6 @@ P2: security: per-origin rate limiting
another way, such as with `%2F` in the path, whatever else the path holds, or another way, such as with `%2F` in the path, whatever else the path holds, or
with a user name and password. It also answers 400 for a source path holding a with a user name and password. It also answers 400 for a source path holding a
`..` segment, as `/v1/image/` refuses one. `..` segment, as `/v1/image/` refuses one.
- 2026-10-16 a `state_dir` whose name holds `%`, `?` or `#` keeps its database
at `state.sqlite3` in that directory (closes #290): the `db_url` derived from
it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a
`?` or `#` ended the path early, and the journal mode parameter was lost. The
derived `db_url` is now built with Go's `net/url`, which writes those
characters as `%25`, `%3F` and `%23`. For a `state_dir` starting with `//` it
starts `file:////`, so SQLite no longer reads the first directory name as a
host.
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips - 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
build a huge image (closes #282): libvips' thumbnail scaled the whole source build a huge image (closes #282): libvips' thumbnail scaled the whole source
to cover the requested size and copied that into memory before it cut out the to cover the requested size and copied that into memory before it cut out the
+9 -5
View File
@@ -359,14 +359,18 @@ func newFromSmartConfig(sc *smartconfig.Config) (*Config, error) {
// the directory name, which SQLite decodes back, so the URL names exactly // the directory name, which SQLite decodes back, so the URL names exactly
// this file. OmitHost writes file:/var/lib/pixa/... instead of // this file. OmitHost writes file:/var/lib/pixa/... instead of
// file:///var/lib/pixa/..., and keeps a relative stateDir from being read // file:///var/lib/pixa/..., and keeps a relative stateDir from being read
// as a host name. A stateDir starting with // keeps the empty host, so the // as a host name. The path written into the URL is stateDir followed by
// URL starts file://// and SQLite does not read the first directory name // /state.sqlite3; when it starts with //, as it does for a stateDir of /
// as a host. // or one starting with //, the empty host is kept, so the URL starts
// file://// and SQLite does not read the first name in the path as a
// host.
func defaultDBURL(stateDir string) string { func defaultDBURL(stateDir string) string {
dbPath := stateDir + "/state.sqlite3"
dbURL := url.URL{ dbURL := url.URL{
Scheme: "file", Scheme: "file",
OmitHost: !strings.HasPrefix(stateDir, "//"), OmitHost: !strings.HasPrefix(dbPath, "//"),
Path: stateDir + "/state.sqlite3", Path: dbPath,
RawQuery: "_pragma=journal_mode(WAL)", RawQuery: "_pragma=journal_mode(WAL)",
} }