關於解決sqlite中加密設計方案缺陷問題

    最近在做sqlite存儲數據庫,但是後臺總是會出現一些離奇的崩潰,但又為數不多,查了好久,定位到使用加密以後才會崩潰;調試中發現問題出現在pagesize出錯後出現的page指向地址有問題,原來sqlite3BtreeOpen的時候取出了file的文件頭,但是這部分是加密過後的數據,因此在此時取出的pagesize是不可預料的,但此時數據庫未有key的存在,考慮到如果更改sqlite的加密機制的話難度和風險較大,為此採用在key的時候同時計算出pagesize,並將其設重設到數據庫中,經檢驗此方法可行,以下貼出重設pagesize的代碼:

int sqlite3_key_resetpagesize(sqlite3 *db)
{
	Btree *pbt = db->aDb[0].pBt;
	Pager *p = sqlite3BtreePager(pbt);

	PgHdr *pPg;
	Pager *pPager;
	unsigned char zDbHeader[100];
	int	nRightPageSize = SQLITE_DEFAULT_PAGE_SIZE;

	Pgno nPage = sqlite3pager_pagecount(p);
	Pgno nSkip = PAGER_MJ_PGNO(p);
	void *pPage;
	Pgno n = 1;// sqlite page is from 1 begin, 0 means no page
	int rc = SQLITE_ERROR;
	if (n != nSkip)
	{
		rc = sqlite3pager_get(p, n, &pPage);
		if(!rc)
		{
			pPg = DATA_TO_PGHDR(pPage);
			pPager = pPg->pPager;
			memcpy(zDbHeader, PGHDR_TO_DATA(pPg), sizeof(zDbHeader));
			nRightPageSize = get2byte(&zDbHeader[16]);
			sqlite3BtreeSetPageSize(pbt, nRightPageSize, -1);
		}
	}
	else
		 return SQLITE_OK;//this page must skip,do not mind it
	
	return rc;
}

附注意:必須在sqlite3BtreeOpen中把pageSizeFixed設置為0;具體看這個值的解釋


另外一種方式是將pagesize設置成一個默認的值,不需要去讀取文件頭,不過就是有點耗硬盤。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值