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

Improved detection and suppression of endless loops in clearDatabasePage().

FossilOrigin-Name: 30011ad2f55cfcacaf23a58ebcc17b17a7b9355e
This commit is contained in:
drh
2015-04-01 13:21:33 +00:00
parent f9d02f3663
commit ccf46d0b90
4 changed files with 17 additions and 15 deletions

View File

@@ -7980,28 +7980,29 @@ static int clearDatabasePage(
int i;
int hdr;
u16 szCell;
u8 hasChildren;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
hasChildren = !pPage->leaf;
pPage->leaf = 1; /* Block looping if the database is corrupt */
if( pPage->bBusy ){
rc = SQLITE_CORRUPT_BKPT;
goto cleardatabasepage_out;
}
pPage->bBusy = 1;
hdr = pPage->hdrOffset;
for(i=0; i<pPage->nCell; i++){
pCell = findCell(pPage, i);
if( hasChildren ){
if( !pPage->leaf ){
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
rc = clearCell(pPage, pCell, &szCell);
if( rc ) goto cleardatabasepage_out;
}
if( hasChildren ){
if( !pPage->leaf ){
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}else if( pnChange ){
@@ -8015,6 +8016,7 @@ static int clearDatabasePage(
}
cleardatabasepage_out:
pPage->bBusy = 0;
releasePage(pPage);
return rc;
}