Add support for attaching databases with non-default page sizes

This commit is contained in:
Nick Parker 2015-01-29 10:39:12 -06:00
parent 7180cded4d
commit a31d65d7c8
4 changed files with 44 additions and 1 deletions

View File

@ -186,6 +186,15 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
}
}
}else
if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
if( zRight ) {
sqlcipher_set_default_pagesize(atoi(zRight));
} else {
char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
sqlite3_free(default_page_size);
}
}else
if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
if( zRight ) {
sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));

View File

@ -180,6 +180,9 @@ int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
void sqlcipher_set_default_pagesize(int page_size);
int sqlcipher_get_default_pagesize();
void sqlcipher_set_default_kdf_iter(int iter);
int sqlcipher_get_default_kdf_iter();

View File

@ -70,6 +70,7 @@ typedef struct {
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
static int default_kdf_iter = PBKDF2_ITER;
static int default_page_size = SQLITE_DEFAULT_PAGE_SIZE;
static unsigned int sqlcipher_activate_count = 0;
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
static sqlcipher_provider *default_provider = NULL;
@ -661,6 +662,14 @@ int sqlcipher_codec_ctx_get_pagesize(codec_ctx *ctx) {
return ctx->page_sz;
}
void sqlcipher_set_default_pagesize(int page_size) {
default_page_size = page_size;
}
int sqlcipher_get_default_pagesize() {
return default_page_size;
}
int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, int nKey) {
int rc;
codec_ctx *ctx;
@ -691,7 +700,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in
cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
*/
if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, SQLITE_DEFAULT_PAGE_SIZE)) != SQLITE_OK) return rc;
if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc;
if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc;

View File

@ -2256,5 +2256,27 @@ do_test can-migrate-with-raw-hex-key {
db close
file delete -force test.db
do_test attach_database_with_non_default_page_size {
sqlite_orig db test2.db
execsql {
PRAGMA key = 'test';
PRAGMA cipher_page_size = 4096;
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) values('one for the money', 'two for the show');
INSERT INTO t1(a,b) values('three to get ready', 'now, go cat, go');
}
db close
sqlite_orig db test.db
execsql {
PRAGMA cipher_default_page_size = 4096;
PRAGMA key = 'test';
ATTACH DATABASE 'test2.db' as test2 KEY 'test';
SELECT count(*) FROM test2.t1;
}
} {2}
db close
file delete -force test.db test2.db
sqlite3_test_control_pending_byte $old_pending_byte
finish_test