mirror of
https://github.com/hanzoai/sqlcipher.git
synced 2026-08-07 09:47:18 +00:00
Reads a database the C library wrote, decrypting pages in memory, on modernc's existing read-only VFS. The pager-level blocker that rules out a read-write VFS does not apply: reading has no WAL frames and no journal records whose checksums could disagree. immutable=1 is load-bearing, not decoration. modernc's read-only VFS reports os.O_RDONLY (0) out of xOpen where SQLite expects SQLITE_OPEN_READONLY (1), and SQLite decides read-only from exactly that flag (pager.c:5044 -> btree.c:2640). So mode=ro silently yields a read-WRITE pager, leaving only that VFS's blanket refusal to open a journal between a caller and its null xWrite. PRAGMA journal_mode=MEMORY removes the accident and the next write SIGSEGVs the process -- reproduced, and now a regression test. immutable=1 routes through pager.c:5081, where readOnly comes from vfsFlags rather than from the VFS, so the pager really is read-only and writes are refused before any journal or page write. It cannot be turned off from SQL, unlike PRAGMA query_only. Read-only is proven at open, not assumed: Open runs a write and refuses to return a handle if it succeeds. Open also refuses a database with a non-empty -wal or -journal beside it. Either may hold committed data not yet in the main file, or uncommitted data that must come out of it, and whether a WAL is checkpointed cannot be settled from the file alone. Answering anyway would mean stale numbers off a ledger. A wrong key is an error at open, not corruption later.