From 1714662877082f3ea1b67dda5b0e3ddc0c178d74 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Jul 2009 17:38:38 +0000 Subject: [PATCH] Improvements to corrupt database detection in defragmentPage(). (CVS 6857) FossilOrigin-Name: 87bbc8d6b68c089c8211c35c11c2f6ac4e46271c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 3869340de4..92e1cf0cf8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sload\sthe\sroot-page\sof\sa\sb-tree\stable/index\swhen\sopening\sa\scursor.\sInstead,\sallow\sit\sto\sbe\sloaded\swhen\sthe\scursor\sis\sfirst\sused\s(in\sfunction\smoveToRoot()).\sAlso\smove\sthe\sroot-page\sflags\ssanity\schecks\sthat\swere\sa\spart\sof\sthe\sOP_OpenRead/OpenWrite\sopcodes\sinto\sthe\smoveToRoot()\sfunction.\s(CVS\s6856) -D 2009-07-07T15:47:12 +C Improvements\sto\scorrupt\sdatabase\sdetection\sin\sdefragmentPage().\s(CVS\s6857) +D 2009-07-07T17:38:39 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -106,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025 F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3 F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119 F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c -F src/btree.c 0cc9c503015fa4970b41833c1a253410ad055ce5 +F src/btree.c 48ac9ac6058c76aefa47aabfc278917c13ae7038 F src/btree.h e761619e76a1125d2d82bd3613b5a7ac7d1ee6f7 F src/btreeInt.h b31e5ac04181c7e2892c33ab06228c551df6233c F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4 @@ -740,7 +740,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P ea7ed16628da29cf4a127a25cbac8ae553e2ac1f -R 6a1dd7b7ae30a801861a4c4d841bbfb1 -U danielk1977 -Z 0d744ad2ad4529f2f9b6cce7c155c49a +P 06dcfe72a6ff3f63639eeb00ec5b5022d10fc55b +R f9eea4246c9dbe036c2c64b098b9ef06 +U drh +Z 144c60a0693475b4f7f9dc98f6a34efa diff --git a/manifest.uuid b/manifest.uuid index 0340bba21b..f97b5820e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06dcfe72a6ff3f63639eeb00ec5b5022d10fc55b \ No newline at end of file +87bbc8d6b68c089c8211c35c11c2f6ac4e46271c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d1f581f796..907a9dc5d9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.656 2009/07/07 15:47:12 danielk1977 Exp $ +** $Id: btree.c,v 1.657 2009/07/07 17:38:39 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1005,7 +1005,6 @@ static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ static int defragmentPage(MemPage *pPage){ int i; /* Loop counter */ int pc; /* Address of a i-th cell */ - int addr; /* Offset of first byte after cell pointer array */ int hdr; /* Offset to the page header */ int size; /* Size of a cell */ int usableSize; /* Number of usable bytes on a page */ @@ -1014,6 +1013,9 @@ static int defragmentPage(MemPage *pPage){ int nCell; /* Number of cells on the page */ unsigned char *data; /* The page data */ unsigned char *temp; /* Temp area for cell content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); @@ -1030,31 +1032,44 @@ static int defragmentPage(MemPage *pPage){ cbrk = get2byte(&data[hdr+5]); memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk); cbrk = usableSize; + iCellFirst = cellOffset + 2*nCell; + iCellLast = usableSize - 4; for(i=0; i=usableSize ){ +#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + /* These conditions have already been verified in sqlite3BtreeInitPage() + ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined + */ + if( pciCellLast ){ return SQLITE_CORRUPT_BKPT; } +#endif + assert( pc>=iCellFirst && pc<=iCellLast ); size = cellSizePtr(pPage, &temp[pc]); cbrk -= size; - if( cbrkusableSize ){ +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + if( cbrk=0 ); +#else + if( cbrkusableSize ){ + return SQLITE_CORRUPT_BKPT; + } +#endif + assert( cbrk+size<=usableSize && cbrk>iCellFirst ); memcpy(&data[cbrk], &temp[pc], size); put2byte(pAddr, cbrk); } - assert( cbrk>=cellOffset+2*nCell ); + assert( cbrk>=iCellFirst ); put2byte(&data[hdr+5], cbrk); data[hdr+1] = 0; data[hdr+2] = 0; data[hdr+7] = 0; - addr = cellOffset+2*nCell; - memset(&data[addr], 0, cbrk-addr); + memset(&data[iCellFirst], 0, cbrk-iCellFirst); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - if( cbrk-addr!=pPage->nFree ){ + if( cbrk-iCellFirst!=pPage->nFree ){ return SQLITE_CORRUPT_BKPT; } return SQLITE_OK;