From: drh Date: Thu, 27 Nov 2008 02:22:10 +0000 (+0000) Subject: Add 19 new assert() statements in btree.c that attempt to detect writing to X-Git-Tag: version-3.6.10~220 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5053fb92227b87e91ba503d926a3b1867f5da5d;p=thirdparty%2Fsqlite.git Add 19 new assert() statements in btree.c that attempt to detect writing to a cache page which is not writeable. (CVS 5964) FossilOrigin-Name: f9c7359065829b016d8cd04304c02509c254fe05 --- diff --git a/manifest b/manifest index 5267ff8942..d1d00613a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C expected\serror\smessage\shas\strailing\sspace\s(CVS\s5963) -D 2008-11-26T20:09:15 +C Add\s19\snew\sassert()\sstatements\sin\sbtree.c\sthat\sattempt\sto\sdetect\swriting\sto\na\scache\spage\swhich\sis\snot\swriteable.\s(CVS\s5964) +D 2008-11-27T02:22:11 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 0aa7bbe3be6acc4045706e3bb3fd0b8f38f4a3b5 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -100,7 +100,7 @@ F src/attach.c 85c6a3d0daf11965b47604190d7cf5597dc88382 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c 4300d311b17fb3c1476623fd895a8feac02a0b08 F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a -F src/btree.c 615a2b9e6173cd0779d0b4c49d7d680acf761e5d +F src/btree.c 372c5b32dc919fed608be57f440d054a46d002fd F src/btree.h 179c3ea813780df78a289a8f5130db18e6d4616e F src/btreeInt.h 8d21590c97b6a2c00cce1f78ed5dc5756e835108 F src/build.c a89e901ea24d8ec845286f9a1fbfd14572a7777e @@ -294,7 +294,7 @@ F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test ecc64c394f5086d02159d8c0a82520f11420cf6a -F test/exclusive2.test 7d2b1c0370f1e1dac4a728bd653f2dea5100fcf6 +F test/exclusive2.test 6bdf254770a843c2933b54bee9ed239934f0a183 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/expr.test 135ed46c049916688171e618c5c14312811618d4 F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8 @@ -662,7 +662,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 68a51f67afd54f1c423206a92b36a33af071d5e1 -R d40b57efd40faad49eaa542c60e0e67a -U pweilbacher -Z 7229044c31c0e6ef537d668b69958244 +P 165bc2d7658e14eda8b375329e4286dc4d048f3a +R 18dffe90de3bb54b15f0c46cfd3b4237 +U drh +Z 80fd0c6dbff82ddebdc7b82929bca8e0 diff --git a/manifest.uuid b/manifest.uuid index de408d5126..2ea8b9c7cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -165bc2d7658e14eda8b375329e4286dc4d048f3a \ No newline at end of file +f9c7359065829b016d8cd04304c02509c254fe05 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1c60f64899..1cfb7bcd9c 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.542 2008/11/26 07:40:30 danielk1977 Exp $ +** $Id: btree.c,v 1.543 2008/11/27 02:22:11 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -754,6 +754,7 @@ static int defragmentPage(MemPage *pPage){ data[hdr+7] = 0; addr = cellOffset+2*nCell; memset(&data[addr], 0, cbrk-addr); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); if( cbrk-addr!=pPage->nFree ){ return SQLITE_CORRUPT_BKPT; } @@ -825,6 +826,7 @@ static int allocateSpace(MemPage *pPage, int nByte){ top -= nByte; assert( cellOffset + 2*nCell <= top ); put2byte(&data[hdr+5], top); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); return top; } @@ -901,6 +903,7 @@ static int freeSpace(MemPage *pPage, int start, int size){ top = get2byte(&data[hdr+5]); put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2])); } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); return SQLITE_OK; } @@ -2119,6 +2122,7 @@ set_child_ptrmaps_out: */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ @@ -4190,6 +4194,7 @@ static int allocateBtreePage( memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); releasePage(pNewTrunk); if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); put4byte(&pPage1->aData[32], iNewTrunk); }else{ rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); @@ -4245,6 +4250,7 @@ static int allocateBtreePage( memcpy(&aData[8+closest*4], &aData[4+k*4], 4); } put4byte(&aData[4], k-1); + assert( sqlite3PagerIswriteable(pTrunk->pDbPage) ); rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1); if( rc==SQLITE_OK ){ sqlite3PagerDontRollback((*ppPage)->pDbPage); @@ -4480,6 +4486,11 @@ static int fillInCell( assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + /* pPage is not necessarily writeable since pCell might be auxiliary + ** buffer space that is separate from the pPage buffer area */ + assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + /* Fill in the header. */ nHeader = 0; if( !pPage->leaf ){ @@ -4552,6 +4563,16 @@ static int fillInCell( releasePage(pToRelease); return rc; } + + /* If pToRelease is not zero than pPrior points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPrior is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + put4byte(pPrior, pgnoOvfl); releasePage(pToRelease); pToRelease = pOvfl; @@ -4562,6 +4583,16 @@ static int fillInCell( } n = nPayload; if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + if( nSrc>0 ){ if( n>nSrc ) n = nSrc; assert( pSrc ); @@ -4605,7 +4636,8 @@ static int dropCell(MemPage *pPage, int idx, int sz){ data = pPage->aData; ptr = &data[pPage->cellOffset + 2*idx]; pc = get2byte(ptr); - if ( (pchdrOffset+6+(pPage->leaf?0:4)) || (pc+sz>pPage->pBt->usableSize) ) { + if( (pchdrOffset+6+(pPage->leaf?0:4)) + || (pc+sz>pPage->pBt->usableSize) ){ return SQLITE_CORRUPT_BKPT; } rc = freeSpace(pPage, pc, sz); @@ -4750,6 +4782,7 @@ static void assemblePage( } assert( totalSize+2*nCell<=pPage->nFree ); assert( pPage->nCell==0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); cellptr = pPage->cellOffset; data = pPage->aData; hdr = pPage->hdrOffset; @@ -4829,6 +4862,7 @@ static int balance_quick(BtCursor *pCur){ if( rc==SQLITE_OK ){ pCell = pPage->aOvfl[0].pCell; szCell = cellSizePtr(pPage, pCell); + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); zeroPage(pNew, pPage->aData[0]); assemblePage(pNew, 1, &pCell, &szCell); pPage->nOverflow = 0; @@ -5431,6 +5465,7 @@ static int balance_nonroot(BtCursor *pCur){ assert( iSpace2<=pBt->pageSize ); rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); if( rc!=SQLITE_OK ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); /* If this is an auto-vacuum database, and not a leaf-data tree, @@ -5468,6 +5503,7 @@ static int balance_nonroot(BtCursor *pCur){ } } } + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); if( nxDiv==pParent->nCell+pParent->nOverflow ){ /* Right-most sibling is the right-most child of pParent */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]); @@ -5571,6 +5607,7 @@ static int balance_shallower(BtCursor *pCur){ } assemblePage(pPage, pChild->nCell, apCell, szCell); /* Copy the right-pointer of the child to the parent. */ + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); put4byte(&pPage->aData[pPage->hdrOffset+8], get4byte(&pChild->aData[pChild->hdrOffset+8])); freePage(pChild); @@ -5631,6 +5668,7 @@ static int balance_deeper(BtCursor *pCur){ pPage = pCur->apPage[0]; pBt = pPage->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3PagerIswriteable(pChild->pDbPage) ); @@ -5652,6 +5690,7 @@ static int balance_deeper(BtCursor *pCur){ pChild->nFree = 0; } assert( pChild->nCell==pPage->nCell ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); @@ -6021,6 +6060,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ } if( rc==SQLITE_OK ){ + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); put4byte(findOverflowCell(pPage, idx), pgnoChild); VVA_ONLY( pCur->pagesShuffled = 0 ); rc = balance(pCur, 0); diff --git a/test/exclusive2.test b/test/exclusive2.test index a78f2a91cb..f38ddcf8bc 100644 --- a/test/exclusive2.test +++ b/test/exclusive2.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: exclusive2.test,v 1.9 2008/08/22 00:25:53 aswift Exp $ +# $Id: exclusive2.test,v 1.10 2008/11/27 02:22:11 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -179,6 +179,7 @@ do_test exclusive2-1.11 { # to prevent memory-induced cache spills. # do_test exclusive2-2.1 { + execsql {PRAGMA cache_size=1000;} execsql {PRAGMA locking_mode = exclusive;} execsql { BEGIN;