mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Size and performance optimization in btreeInitPage() in the freeblock
validation step. FossilOrigin-Name: 57deb1b412e0c328528f2b4d697e326bfd028dca
This commit is contained in:
33
src/btree.c
33
src/btree.c
@@ -1743,7 +1743,7 @@ static int btreeInitPage(MemPage *pPage){
|
||||
assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
|
||||
|
||||
if( !pPage->isInit ){
|
||||
u16 pc; /* Address of a freeblock within pPage->aData[] */
|
||||
u32 pc; /* Address of a freeblock within pPage->aData[] */
|
||||
u8 hdr; /* Offset to beginning of page header */
|
||||
u8 *data; /* Equal to pPage->aData */
|
||||
BtShared *pBt; /* The main btree structure */
|
||||
@@ -1823,25 +1823,30 @@ static int btreeInitPage(MemPage *pPage){
|
||||
** freeblocks. */
|
||||
pc = get2byte(&data[hdr+1]);
|
||||
nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
|
||||
while( pc>0 ){
|
||||
u16 next, size;
|
||||
if( pc<iCellFirst || pc>iCellLast ){
|
||||
if( pc>0 ){
|
||||
u32 next, size;
|
||||
if( pc<iCellFirst ){
|
||||
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
|
||||
** always be at least one cell before the first freeblock.
|
||||
**
|
||||
** Or, the freeblock is off the end of the page
|
||||
*/
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
next = get2byte(&data[pc]);
|
||||
size = get2byte(&data[pc+2]);
|
||||
if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
|
||||
/* Free blocks must be in ascending order. And the last byte of
|
||||
** the free-block must lie on the database page. */
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
while( 1 ){
|
||||
if( pc>iCellLast ){
|
||||
return SQLITE_CORRUPT_BKPT; /* Freeblock off the end of the page */
|
||||
}
|
||||
next = get2byte(&data[pc]);
|
||||
size = get2byte(&data[pc+2]);
|
||||
nFree = nFree + size;
|
||||
if( next<=pc+size+3 ) break;
|
||||
pc = next;
|
||||
}
|
||||
if( next>0 ){
|
||||
return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */
|
||||
}
|
||||
if( pc+size>usableSize ){
|
||||
return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */
|
||||
}
|
||||
nFree = nFree + size;
|
||||
pc = next;
|
||||
}
|
||||
|
||||
/* At this point, nFree contains the sum of the offset to the start
|
||||
|
Reference in New Issue
Block a user