Version and environment
Reproduced on SQLCipher commit 810db22f575ee7cf94ea96a3e91622b5fcece3dc, Linux amd64, with SQLite 3.53.3 / SQLCipher 4.17.0 Community and the bundled SQLCipher 3.0 testkey fixture.
Describe the bug
The migration code derives <database filename>-migrated and places that path directly inside ATTACH DATABASE '%s'. A valid filename containing ' therefore breaks the internal SQL string. The identical old-format database migrates under a normal filename but fails when only its filename changes to include a single quote.
Minimal reproduction
bash sqlcipher-026-pragma-cipher-migrate-fails-for-valid-old-format-datab-bee6fa14/poc/revalidate_sqlcipher_026.sh
The essential setup is:
cp sqlcipher-3.0-testkey.db /tmp/c026-normal.db
cp sqlcipher-3.0-testkey.db "/tmp/c026-quote'key.db"
sqlcipher /tmp/c026-normal.db "PRAGMA key='testkey'; PRAGMA cipher_migrate; SELECT count(*) FROM sqlite_schema;"
sqlcipher "/tmp/c026-quote'key.db" "PRAGMA key='testkey'; PRAGMA cipher_migrate; SELECT count(*) FROM sqlite_schema;"
The wrapper also reopens both files after migration.
Actual behavior/output
normal_schema_count|1
normal_status|0
normal_reopen_count|1
quote_status|1
quote_reopen_status|1
Stderr includes sqlcipher_codec_ctx_migrate: attach failed, error code 1, file is not a database, and failure to delete /tmp/c026-quote'key.db-migrated.
Expected behavior
Both files contain identical valid legacy databases, and ' is valid in the POSIX filename. cipher_migrate should safely quote/bind its internally derived path and migrate both copies.
Impact and scope
Users cannot migrate valid legacy databases at paths containing a single quote. Applications may need unsafe renaming workarounds and can be left with a failed migration artifact.
Relevant source/root cause
src/sqlcipher.c:2185 derives the migration filename. Around :2204, it constructs ATTACH DATABASE '%s' as migrate; without escaping the path as an SQL string. The subsequent failure aligns with this attach step; existing compatibility tests use only ordinary filenames.
Suggested regression test
Copy a known SQLCipher 3 fixture to a path containing ', run cipher_migrate, and verify current-format reopen/query success. Add other SQL-string-special path characters and assert cleanup of the -migrated file on both success and failure.
Reproduction bundle
Attached: sqlcipher-026-pragma-cipher-migrate-fails-for-valid-old-format-datab-bee6fa14_attachment.zip. It contains the focused PoC, validation evidence, and candidate metadata.
sqlcipher-026-pragma-cipher-migrate-fails-for-valid-old-format-datab-bee6fa14_attachment.zip
Version and environment
Reproduced on SQLCipher commit
810db22f575ee7cf94ea96a3e91622b5fcece3dc, Linux amd64, with SQLite 3.53.3 / SQLCipher 4.17.0 Community and the bundled SQLCipher 3.0testkeyfixture.Describe the bug
The migration code derives
<database filename>-migratedand places that path directly insideATTACH DATABASE '%s'. A valid filename containing'therefore breaks the internal SQL string. The identical old-format database migrates under a normal filename but fails when only its filename changes to include a single quote.Minimal reproduction
The essential setup is:
The wrapper also reopens both files after migration.
Actual behavior/output
Stderr includes
sqlcipher_codec_ctx_migrate: attach failed, error code 1,file is not a database, and failure to delete/tmp/c026-quote'key.db-migrated.Expected behavior
Both files contain identical valid legacy databases, and
'is valid in the POSIX filename.cipher_migrateshould safely quote/bind its internally derived path and migrate both copies.Impact and scope
Users cannot migrate valid legacy databases at paths containing a single quote. Applications may need unsafe renaming workarounds and can be left with a failed migration artifact.
Relevant source/root cause
src/sqlcipher.c:2185derives the migration filename. Around:2204, it constructsATTACH DATABASE '%s' as migrate;without escaping the path as an SQL string. The subsequent failure aligns with this attach step; existing compatibility tests use only ordinary filenames.Suggested regression test
Copy a known SQLCipher 3 fixture to a path containing
', runcipher_migrate, and verify current-format reopen/query success. Add other SQL-string-special path characters and assert cleanup of the-migratedfile on both success and failure.Reproduction bundle
Attached:
sqlcipher-026-pragma-cipher-migrate-fails-for-valid-old-format-datab-bee6fa14_attachment.zip. It contains the focused PoC, validation evidence, and candidate metadata.sqlcipher-026-pragma-cipher-migrate-fails-for-valid-old-format-datab-bee6fa14_attachment.zip