Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/sqlcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,13 @@ static int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
/* everything above exits through cleanup, nothing here has touched the database */
migrate:

/* the btree also sees URI mode=ro and immutable=1, which openFlags miss */
if(sqlite3BtreeIsReadonly(db->aDb[0].pBt)) {
sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: cannot migrate a read-only database", __func__);
rc = SQLITE_READONLY;
goto cleanup;
}

if(!(temp = sqlite3_mprintf("%s-migrated", db_filename))) {
sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: failed to format temp filename", __func__);
rc = SQLITE_NOMEM;
Expand Down
38 changes: 38 additions & 0 deletions test/sqlcipher-compatibility.test
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,44 @@ do_test migrate-current-format-noop {
db close
file delete -force test.db

# a read-only connection refuses to migrate and leaves the file untouched
foreach {tn name opts} {
uri-mode-ro file:test.db?mode=ro {}
uri-immutable file:test.db?immutable=1 {}
open-readonly test.db {-readonly 1}
} {
do_test migrate-readonly-$tn {
file copy -force $sampleDir/sqlcipher-3.0-testkey.db test.db
set orig [hexio_read test.db 0 [file size test.db]]
sqlite_orig db $name {*}$opts
set rc {}
lappend rc [execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_migrate;
PRAGMA cipher_compatibility = 3;
SELECT count(*) FROM sqlite_schema;
}]
db close
lappend rc [file exists test.db-migrated]
lappend rc [string equal $orig [hexio_read test.db 0 [file size test.db]]]
} {{ok 8 1} 0 1}
file delete -force test.db
}

# a read-only connection on a current-format database reports OK
do_test migrate-readonly-current-format-noop {
file copy -force $sampleDir/sqlcipher-4.0-testkey.db test.db
sqlite_orig db file:test.db?mode=ro

execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_migrate;
SELECT count(*) FROM sqlite_schema;
}
} {ok 0 1}
db close
file delete -force test.db

# migrate should fail after key derivation occurs
# key database, then force key derivation by touching schema
# shoudl report SQLITE_MISUSE
Expand Down