Skip to content

Commit a31d65d

Browse files
Add support for attaching databases with non-default page sizes
1 parent 7180cde commit a31d65d

4 files changed

Lines changed: 44 additions & 1 deletion

File tree

src/crypto.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
186186
}
187187
}
188188
}else
189+
if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
190+
if( zRight ) {
191+
sqlcipher_set_default_pagesize(atoi(zRight));
192+
} else {
193+
char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
194+
codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
195+
sqlite3_free(default_page_size);
196+
}
197+
}else
189198
if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
190199
if( zRight ) {
191200
sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));

src/crypto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
180180
int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
181181
int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
182182

183+
void sqlcipher_set_default_pagesize(int page_size);
184+
int sqlcipher_get_default_pagesize();
185+
183186
void sqlcipher_set_default_kdf_iter(int iter);
184187
int sqlcipher_get_default_kdf_iter();
185188

src/crypto_impl.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct {
7070
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
7171
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
7272
static int default_kdf_iter = PBKDF2_ITER;
73+
static int default_page_size = SQLITE_DEFAULT_PAGE_SIZE;
7374
static unsigned int sqlcipher_activate_count = 0;
7475
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
7576
static sqlcipher_provider *default_provider = NULL;
@@ -661,6 +662,14 @@ int sqlcipher_codec_ctx_get_pagesize(codec_ctx *ctx) {
661662
return ctx->page_sz;
662663
}
663664

665+
void sqlcipher_set_default_pagesize(int page_size) {
666+
default_page_size = page_size;
667+
}
668+
669+
int sqlcipher_get_default_pagesize() {
670+
return default_page_size;
671+
}
672+
664673
int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, int nKey) {
665674
int rc;
666675
codec_ctx *ctx;
@@ -691,7 +700,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
691700
in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in
692701
cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
693702
*/
694-
if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, SQLITE_DEFAULT_PAGE_SIZE)) != SQLITE_OK) return rc;
703+
if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
695704

696705
if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc;
697706
if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc;

test/crypto.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,5 +2256,27 @@ do_test can-migrate-with-raw-hex-key {
22562256
db close
22572257
file delete -force test.db
22582258

2259+
do_test attach_database_with_non_default_page_size {
2260+
sqlite_orig db test2.db
2261+
execsql {
2262+
PRAGMA key = 'test';
2263+
PRAGMA cipher_page_size = 4096;
2264+
CREATE TABLE t1(a,b);
2265+
INSERT INTO t1(a,b) values('one for the money', 'two for the show');
2266+
INSERT INTO t1(a,b) values('three to get ready', 'now, go cat, go');
2267+
}
2268+
db close
2269+
2270+
sqlite_orig db test.db
2271+
execsql {
2272+
PRAGMA cipher_default_page_size = 4096;
2273+
PRAGMA key = 'test';
2274+
ATTACH DATABASE 'test2.db' as test2 KEY 'test';
2275+
SELECT count(*) FROM test2.t1;
2276+
}
2277+
} {2}
2278+
db close
2279+
file delete -force test.db test2.db
2280+
22592281
sqlite3_test_control_pending_byte $old_pending_byte
22602282
finish_test

0 commit comments

Comments
 (0)