Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Earlier detection of freelist corruption in the page allocation routines. (CVS 6718) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e557c8e5846f9c4eaaeb3bd07614ac10 |
User & Date: | drh 2009-06-04 19:06:10.000 |
Context
2009-06-05
| ||
14:17 | Take care that a corrupt variable-length integer does not cause 32-bit integer overflow when parsing a record format, nor cause excessively large memory allocations. (CVS 6719) (check-in: 38b20327a8 user: drh tags: trunk) | |
2009-06-04
| ||
19:06 | Earlier detection of freelist corruption in the page allocation routines. (CVS 6718) (check-in: e557c8e584 user: drh tags: trunk) | |
17:02 | Fix an assertion fault in balance_quick() that occurs when an interior btree node has zero cells due to database corruption. Also update the corrupt7.test result vectors for a couple of cases where the error report on database corruption changed due to earlier detection. (CVS 6717) (check-in: 1335e4440f user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $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. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 | ){ MemPage *pPage1; int rc; int n; /* Number of pages on the freelist */ int k; /* Number of leaves on the trunk of the freelist */ MemPage *pTrunk = 0; MemPage *pPrevTrunk = 0; assert( sqlite3_mutex_held(pBt->mutex) ); pPage1 = pBt->pPage1; n = get4byte(&pPage1->aData[36]); if( n>0 ){ /* There are pages on the freelist. Reuse one of those pages. */ Pgno iTrunk; u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ /* If the 'exact' parameter was true and a query of the pointer-map ** shows that the page 'nearby' is somewhere on the free-list, then ** the entire-list will be searched for that page. */ #ifndef SQLITE_OMIT_AUTOVACUUM | > > > > > | | 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 | ){ MemPage *pPage1; int rc; int n; /* Number of pages on the freelist */ 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; u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ /* If the 'exact' parameter was true and a query of the pointer-map ** shows that the page 'nearby' is somewhere on the free-list, then ** the entire-list will be searched for that page. */ #ifndef SQLITE_OMIT_AUTOVACUUM if( exact && nearby<=mxPage ){ u8 eType; assert( nearby>0 ); assert( pBt->autoVacuum ); rc = ptrmapGet(pBt, nearby, &eType, 0); if( rc ) return rc; if( eType==PTRMAP_FREEPAGE ){ searchList = 1; |
︙ | ︙ | |||
4438 4439 4440 4441 4442 4443 4444 | do { pPrevTrunk = pTrunk; if( pPrevTrunk ){ iTrunk = get4byte(&pPrevTrunk->aData[0]); }else{ iTrunk = get4byte(&pPage1->aData[32]); } | > > > | > > > > > | 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 | do { pPrevTrunk = pTrunk; if( pPrevTrunk ){ iTrunk = get4byte(&pPrevTrunk->aData[0]); }else{ iTrunk = get4byte(&pPage1->aData[32]); } 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 ** allocated page */ assert( pPrevTrunk==0 ); rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ |
︙ | ︙ | |||
4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 | }else{ /* The trunk page is required by the caller but it contains ** pointers to free-list leaves. The first leaf becomes a trunk ** page in this case. */ MemPage *pNewTrunk; Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); if( rc!=SQLITE_OK ){ goto end_allocate_page; } rc = sqlite3PagerWrite(pNewTrunk->pDbPage); if( rc!=SQLITE_OK ){ releasePage(pNewTrunk); | > > > > | 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 | }else{ /* The trunk page is required by the caller but it contains ** pointers to free-list leaves. The first leaf becomes a trunk ** page in this case. */ 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; } rc = sqlite3PagerWrite(pNewTrunk->pDbPage); if( rc!=SQLITE_OK ){ releasePage(pNewTrunk); |
︙ | ︙ | |||
4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 | } } }else{ closest = 0; } iPage = get4byte(&aData[8+closest*4]); if( !searchList || iPage==nearby ){ int noContent; Pgno nPage; *pPgno = iPage; nPage = pagerPagecount(pBt); if( *pPgno>nPage ){ /* Free page off the end of the file */ | > > > > | 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 | } } }else{ closest = 0; } 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; *pPgno = iPage; nPage = pagerPagecount(pBt); if( *pPgno>nPage ){ /* Free page off the end of the file */ |
︙ | ︙ |