Escape the database path in the SQLite connection string (closes #55) #87

Merged
clawbot merged 1 commits from issue-55-escape-database-path into next 2026-10-04 15:13:20 +02:00
Collaborator

Fixes #55.

openDB (db.go) built the SQLite connection string as file: + path + ? + parameters, unescaped. A ? or # in the path ended the file name and a % started an escape, so scan could silently create and fill a database under a shortened name. The path now goes into a net/url file: URL, which escapes it. The read-write connection for scan and the read-only one for report and trees both come from that one call.

What the diff does not show:

  • SQLite reads what follows file:// up to the next / as a host name. So an absolute path is written after an empty host (file:///abs) and a relative path with none (file:rel): OmitHost: !filepath.IsAbs(path). Leaving out the host for every path breaks a path starting with //; writing one for every path breaks relative paths. The test has a case for each.
  • Judgement call: the path is not cleaned or made absolute. Doing either would resolve .. without following symlinks, so the database could end up a different file from the lock file and from the existence check, which both use the path as given.
  • The test's file name holds %25 rather than a bare %. %25 is a valid escape, so under the old code the scan quietly writes a file named a instead of failing on a bad escape, which is the failure the issue describes.

README §Database now says the path names the file exactly and a relative path is relative to the working directory.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/sfdupes/issues/55. `openDB` (`db.go`) built the SQLite connection string as `file:` + path + `?` + parameters, unescaped. A `?` or `#` in the path ended the file name and a `%` started an escape, so `scan` could silently create and fill a database under a shortened name. The path now goes into a `net/url` `file:` URL, which escapes it. The read-write connection for `scan` and the read-only one for `report` and `trees` both come from that one call. What the diff does not show: - SQLite reads what follows `file://` up to the next `/` as a host name. So an absolute path is written after an empty host (`file:///abs`) and a relative path with none (`file:rel`): `OmitHost: !filepath.IsAbs(path)`. Leaving out the host for every path breaks a path starting with `//`; writing one for every path breaks relative paths. The test has a case for each. - Judgement call: the path is not cleaned or made absolute. Doing either would resolve `..` without following symlinks, so the database could end up a different file from the lock file and from the existence check, which both use the path as given. - The test's file name holds `%25` rather than a bare `%`. `%25` is a valid escape, so under the old code the scan quietly writes a file named `a` instead of failing on a bad escape, which is the failure the issue describes. README §Database now says the path names the file exactly and a relative path is relative to the working directory. Model: opus-5-5
clawbot added the needs-review label 2026-10-04 14:49:45 +02:00
clawbot self-assigned this 2026-10-04 14:49:45 +02:00
clawbot added 1 commit 2026-10-04 14:49:45 +02:00
openDB put the path into the connection string unescaped, so a ? or #
in it ended the file name and a % started an escape: scan could
silently fill a database under a shortened name. The path now goes
through net/url as a file: URI. An absolute path gets an empty host and
a relative path none, because SQLite reads what follows file:// up to
the next slash as a host name. The path is not cleaned, so it stays
exactly what the operator gave.

A test runs scan, report and trees against such a file name given as an
absolute path, as one starting with //, and as a relative path, and
checks that only that file and its lock file exist afterwards.

Model: opus-5-5
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit 722675f153 into next 2026-10-04 15:13:20 +02:00
clawbot deleted branch issue-55-escape-database-path 2026-10-04 15:13:20 +02:00
Sign in to join this conversation.