Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change some assert()s that could fail if the database is corrupt to return SQLITE_CORRUPT instead. (CVS 2223) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2d58c0afa769d49c8819ea4982bc20ae |
User & Date: | danielk1977 2005-01-17 02:12:19.000 |
Context
2005-01-17
| ||
03:40 | Fix a memory leak that occurs as a result of an IO error. (CVS 2224) (check-in: 1edfdcbf14 user: danielk1977 tags: trunk) | |
02:12 | Change some assert()s that could fail if the database is corrupt to return SQLITE_CORRUPT instead. (CVS 2223) (check-in: 2d58c0afa7 user: danielk1977 tags: trunk) | |
01:33 | Have sqlite3pager_get() return SQLITE_CORRUPT for a page number greater than 2^31. (CVS 2222) (check-in: feb49d10e8 user: danielk1977 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.240 2005/01/17 02:12:19 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
478 479 480 481 482 483 484 | static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){ u8 *pPtrmap; /* The pointer map page */ Pgno iPtrmap; /* The pointer map page number */ int offset; /* Offset in pointer map page */ int rc; assert( pBt->autoVacuum ); | | > > | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){ u8 *pPtrmap; /* The pointer map page */ Pgno iPtrmap; /* The pointer map page number */ int offset; /* Offset in pointer map page */ int rc; assert( pBt->autoVacuum ); if( key==0 ){ return SQLITE_CORRUPT; } iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); if( rc!=SQLITE_OK ){ return rc; } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); |
︙ | ︙ | |||
524 525 526 527 528 529 530 531 532 533 534 535 536 537 | } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); if( pEType ) *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); sqlite3pager_unref(pPtrmap); return SQLITE_OK; } #endif /* SQLITE_OMIT_AUTOVACUUM */ /* ** Given a btree page and a cell index (0 means the first cell on | > | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 | } offset = PTRMAP_PTROFFSET(pBt->usableSize, key); if( pEType ) *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); sqlite3pager_unref(pPtrmap); if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT; return SQLITE_OK; } #endif /* SQLITE_OMIT_AUTOVACUUM */ /* ** Given a btree page and a cell index (0 means the first cell on |
︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 | int isInitOrig = pPage->isInit; Pgno pgno = pPage->pgno; initPage(pPage, 0); nCell = pPage->nCell; for(i=0; i<nCell; i++){ | < | 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 | int isInitOrig = pPage->isInit; Pgno pgno = pPage->pgno; initPage(pPage, 0); nCell = pPage->nCell; for(i=0; i<nCell; i++){ u8 *pCell = findCell(pPage, i); rc = ptrmapPutOvflPtr(pPage, pCell); if( rc!=SQLITE_OK ){ goto set_child_ptrmaps_out; } |
︙ | ︙ | |||
1645 1646 1647 1648 1649 1650 1651 | ** ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow ** page pointed to by one of the cells on pPage. ** ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next ** overflow page in the list. */ | | < | > > | 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 | ** ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow ** page pointed to by one of the cells on pPage. ** ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next ** overflow page in the list. */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ return SQLITE_CORRUPT; } put4byte(pPage->aData, iTo); }else{ int isInitOrig = pPage->isInit; int i; int nCell; initPage(pPage, 0); |
︙ | ︙ | |||
1679 1680 1681 1682 1683 1684 1685 | put4byte(pCell, iTo); break; } } } if( i==nCell ){ | | | > > > | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 | put4byte(pCell, iTo); break; } } } if( i==nCell ){ if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ return SQLITE_CORRUPT; } put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); } pPage->isInit = isInitOrig; } return SQLITE_OK; } /* ** Move the open database page pDbPage to location iFreePage in the ** database. The pDbPage reference remains valid. */ |
︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 | rc = setChildPtrmaps(pDbPage); if( rc!=SQLITE_OK ){ return rc; } }else{ Pgno nextOvfl = get4byte(pDbPage->aData); if( nextOvfl!=0 ){ | < | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 | rc = setChildPtrmaps(pDbPage); if( rc!=SQLITE_OK ){ return rc; } }else{ Pgno nextOvfl = get4byte(pDbPage->aData); if( nextOvfl!=0 ){ rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); if( rc!=SQLITE_OK ){ return rc; } } } |
︙ | ︙ | |||
1755 1756 1757 1758 1759 1760 1761 | return rc; } rc = sqlite3pager_write(pPtrPage->aData); if( rc!=SQLITE_OK ){ releasePage(pPtrPage); return rc; } | | < > > > | 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 | return rc; } rc = sqlite3pager_write(pPtrPage->aData); if( rc!=SQLITE_OK ){ releasePage(pPtrPage); return rc; } rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); releasePage(pPtrPage); if( rc==SQLITE_OK ){ rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); } } return rc; } /* Forward declaration required by autoVacuumCommit(). */ static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); |
︙ | ︙ | |||
1789 1790 1791 1792 1793 1794 1795 | MemPage *pFreeMemPage = 0; /* "" */ #ifndef NDEBUG int nRef = *sqlite3pager_stats(pPager); #endif assert( pBt->autoVacuum ); | | > > | 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 | MemPage *pFreeMemPage = 0; /* "" */ #ifndef NDEBUG int nRef = *sqlite3pager_stats(pPager); #endif assert( pBt->autoVacuum ); if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ return SQLITE_CORRUPT; } /* Figure out how many free-pages are in the database. If there are no ** free pages, then auto-vacuum is a no-op. */ nFreeList = get4byte(&pBt->pPage1->aData[36]); if( nFreeList==0 ){ *nTrunc = 0; |
︙ | ︙ |