diff --git a/src/crypto.c b/src/crypto.c index fed8ab3..057d303 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -293,11 +293,13 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */ rc = sqlite3PagerPagecount(pPager, &page_count); for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ - rc = sqlite3PagerGet(pPager, pgno, &page); - if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */ - rc = sqlite3PagerWrite(page); - if(rc == SQLITE_OK) { - sqlite3PagerUnref(page); + if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ + rc = sqlite3PagerGet(pPager, pgno, &page); + if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */ + rc = sqlite3PagerWrite(page); + if(rc == SQLITE_OK) { + sqlite3PagerUnref(page); + } } } } diff --git a/src/pager.c b/src/pager.c index e39fd64..e15893d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5363,11 +5363,13 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ /* BEGIN CRYPTO */ #ifdef SQLITE_HAS_CODEC - int sqlite3pager_get_codec(Pager *pPager, void **ctx) { *ctx = pPager->pCodecArg; } +int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) { + return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0; +} #endif /* END CRYPTO */ diff --git a/test/codec.test b/test/codec.test index 3bbb8b9..e63a00b 100644 --- a/test/codec.test +++ b/test/codec.test @@ -78,5 +78,66 @@ do_test codec-1.5 { } } {1 {file is encrypted or is not a database}} +# open using raw hex key +do_test codec-1.6 { + db close + sqlite_orig db test.db + execsql { + PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836489'"; + SELECT * from t1; + } +} {test1 test2} + +# test invalid hex key fails +do_test codec-1.7 { + db close + sqlite_orig db test.db + catchsql { + PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'"; + SELECT name FROM sqlite_master WHERE type='table'; + } +} {1 {file is encrypted or is not a database}} + +# test a large number of inserts in a transaction for multiple pages +do_test codec-1.8 { + db close + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + BEGIN; + CREATE TABLE t2(a,b); + } + for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + execsql "INSERT INTO t2 VALUES($i,$r);" + } + execsql { + COMMIT; + SELECT count(*) FROM t2; + } +} {25000} + +# test initial rekey +do_test codec-1.9 { + db close + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA rekey = 'testkeynew'; + } + db close +} {} + +# test that now the new key opens the database +# now close database re-open with new key +do_test codec-1.10 { + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkeynew'; + SELECT count(*) FROM t2; + } +} {25000} + + db close finish_test