1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Earlier detection of freelist corruption in the page allocation routines. (CVS 6718)

FossilOrigin-Name: e557c8e5846f9c4eaaeb3bd07614ac101bb0b3d0
This commit is contained in:
drh
2009-06-04 19:06:09 +00:00
parent d46b6c23d3
commit 1662b5a6f9
3 changed files with 31 additions and 10 deletions

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.616 2009/06/04 17:02:51 drh Exp $
** $Id: btree.c,v 1.617 2009/06/04 19:06:10 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
@@ -4397,10 +4397,15 @@ static int allocateBtreePage(
int k; /* Number of leaves on the trunk of the freelist */
MemPage *pTrunk = 0;
MemPage *pPrevTrunk = 0;
Pgno mxPage; /* Total size of the database file */
assert( sqlite3_mutex_held(pBt->mutex) );
pPage1 = pBt->pPage1;
mxPage = pagerPagecount(pBt);
n = get4byte(&pPage1->aData[36]);
if( n>mxPage ){
return SQLITE_CORRUPT_BKPT;
}
if( n>0 ){
/* There are pages on the freelist. Reuse one of those pages. */
Pgno iTrunk;
@@ -4411,7 +4416,7 @@ static int allocateBtreePage(
** the entire-list will be searched for that page.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
if( exact && nearby<=pagerPagecount(pBt) ){
if( exact && nearby<=mxPage ){
u8 eType;
assert( nearby>0 );
assert( pBt->autoVacuum );
@@ -4442,13 +4447,21 @@ static int allocateBtreePage(
}else{
iTrunk = get4byte(&pPage1->aData[32]);
}
rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
if( iTrunk>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
goto end_allocate_page;
}
k = get4byte(&pTrunk->aData[4]);
if( k>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
goto end_allocate_page;
}
if( k==0 && !searchList ){
/* The trunk has no leaves and the list is not being searched.
** So extract the trunk page itself and use it as the newly
@@ -4492,6 +4505,10 @@ static int allocateBtreePage(
*/
MemPage *pNewTrunk;
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
if( iNewTrunk>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
goto end_allocate_page;
}
rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
@@ -4546,6 +4563,10 @@ static int allocateBtreePage(
}
iPage = get4byte(&aData[8+closest*4]);
if( iPage>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
goto end_allocate_page;
}
if( !searchList || iPage==nearby ){
int noContent;
Pgno nPage;