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

In SQLITE_DEBUG mode, attempt to log the page number of the database that

contained the problem when SQLITE_CORRUPT errors are seen.

FossilOrigin-Name: e39795d7d798d5249c7bd2a0f6ff891b455f4300a3d638c39a4668323b367666
This commit is contained in:
drh
2017-06-07 22:32:59 +00:00
parent d1417ee1cb
commit cc97ca4c08
5 changed files with 69 additions and 49 deletions

View File

@@ -1,5 +1,5 @@
C Add\sthe\sSQLITE_DEFAULT_ROWEST\scompile-time\soption\sfor\schanging\sthe\sestimated\nnumber\sof\srows\sin\stables\sthat\slack\ssqlite_stat1\sentries. C In\sSQLITE_DEBUG\smode,\sattempt\sto\slog\sthe\spage\snumber\sof\sthe\sdatabase\sthat\ncontained\sthe\sproblem\swhen\sSQLITE_CORRUPT\serrors\sare\sseen.
D 2017-06-06T18:20:43.972 D 2017-06-07T22:32:59.780
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
@@ -348,7 +348,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c 8ac6ae352c63998228718b5f11faa0da2676710898a47284de78e96cb41dca35 F src/btree.c a13e516b945c82536ea821c6d68976dd95995ecc93a0843739ba2726654848de
F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610 F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340 F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340
@@ -370,7 +370,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 974499a3999d339a4c1ba8ef129a988d9f136b3789e423808b38cdc19d28adbe F src/insert.c 974499a3999d339a4c1ba8ef129a988d9f136b3789e423808b38cdc19d28adbe
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9
F src/main.c 1054e4dbb4fcca84246ed48b35164a996f5a52daa56c275157a5d583c0e2cd00 F src/main.c 65eb6093de90ab4372f2ae0d0cd0acfe718ea26ef0145435e0d9eecb854c9d7e
F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -410,7 +410,7 @@ F src/shell.c eca7e7fe8dae859aa56e462c5b35c735976fa1e5e1d7a90fd5a32aa4615c1825
F src/sqlite.h.in ad7f4101e3613b1134d1ad6c61ff385424ffac0d542627fd31f26667fdd91c94 F src/sqlite.h.in ad7f4101e3613b1134d1ad6c61ff385424ffac0d542627fd31f26667fdd91c94
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
F src/sqliteInt.h 82800fc19fbdeb35a0773c5d727da717652f4c421d191d2460219c7aab953462 F src/sqliteInt.h f90955604b4d8e5a1f672bd230978640be89e0bbbf833d352cf4945ce3a799df
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1582,7 +1582,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 9eea3670e77e2f831b7c00ae2d65a5583f9cad626d9ab286f92582ef29ecd4e3 P 234ede26e30f20e6c33002739ed8be35dbfb5c77700bd857ff31072b9b7df347
R de51f7d1edc1449c33df63cd75f44fee R c04dd611e76a5178eefb81efcaf86a63
U drh U drh
Z db2906277b1736b6942b7d17ecf808c4 Z c18dd5659d184ab0c25e4eb565cb031f

View File

@@ -1 +1 @@
234ede26e30f20e6c33002739ed8be35dbfb5c77700bd857ff31072b9b7df347 e39795d7d798d5249c7bd2a0f6ff891b455f4300a3d638c39a4668323b367666

View File

@@ -771,7 +771,7 @@ static int btreeMoveto(
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 ){ if( pIdxKey->nField==0 ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
goto moveto_done; goto moveto_done;
} }
}else{ }else{
@@ -1000,7 +1000,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
sqlite3PagerUnref(pDbPage); sqlite3PagerUnref(pDbPage);
if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap);
return SQLITE_OK; return SQLITE_OK;
} }
@@ -1385,7 +1385,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
int sz = get2byte(&data[iFree+2]); int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]); int top = get2byte(&data[hdr+5]);
if( iFree2 ){ if( iFree2 ){
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT; if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
sz2 = get2byte(&data[iFree2+2]); sz2 = get2byte(&data[iFree2+2]);
assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
@@ -1416,13 +1416,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** if PRAGMA cell_size_check=ON. ** if PRAGMA cell_size_check=ON.
*/ */
if( pc<iCellFirst || pc>iCellLast ){ if( pc<iCellFirst || pc>iCellLast ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
assert( pc>=iCellFirst && pc<=iCellLast ); assert( pc>=iCellFirst && pc<=iCellLast );
size = pPage->xCellSize(pPage, &src[pc]); size = pPage->xCellSize(pPage, &src[pc]);
cbrk -= size; cbrk -= size;
if( cbrk<iCellFirst || pc+size>usableSize ){ if( cbrk<iCellFirst || pc+size>usableSize ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
testcase( cbrk+size==usableSize ); testcase( cbrk+size==usableSize );
@@ -1442,7 +1442,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
defragment_out: defragment_out:
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
assert( cbrk>=iCellFirst ); assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk); put2byte(&data[hdr+5], cbrk);
@@ -1481,7 +1481,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
/* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
** increasing offset. */ ** increasing offset. */
if( pc>usableSize-4 || pc<iAddr+4 ){ if( pc>usableSize-4 || pc<iAddr+4 ){
*pRc = SQLITE_CORRUPT_BKPT; *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
return 0; return 0;
} }
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
@@ -1492,7 +1492,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
testcase( x==4 ); testcase( x==4 );
testcase( x==3 ); testcase( x==3 );
if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
*pRc = SQLITE_CORRUPT_BKPT; *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
return 0; return 0;
}else if( x<4 ){ }else if( x<4 ){
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -1559,7 +1559,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( top==0 && pPage->pBt->usableSize==65536 ){ if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536; top = 65536;
}else{ }else{
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
} }
@@ -1655,11 +1655,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
if( iFreeBlk<iPtr+4 ){ if( iFreeBlk<iPtr+4 ){
if( iFreeBlk==0 ) break; if( iFreeBlk==0 ) break;
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
iPtr = iFreeBlk; iPtr = iFreeBlk;
} }
if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT; if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
assert( iFreeBlk>iPtr || iFreeBlk==0 ); assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* At this point: /* At this point:
@@ -1670,9 +1670,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
*/ */
if( iFreeBlk && iEnd+3>=iFreeBlk ){ if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd; nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
if( iEnd > pPage->pBt->usableSize ) return SQLITE_CORRUPT_BKPT; if( iEnd > pPage->pBt->usableSize ){
return SQLITE_CORRUPT_PGNO(pPage->pgno);
}
iSize = iEnd - iStart; iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]); iFreeBlk = get2byte(&data[iFreeBlk]);
} }
@@ -1684,20 +1686,20 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( iPtr>hdr+1 ){ if( iPtr>hdr+1 ){
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){ if( iPtrEnd+3>=iStart ){
if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
nFrag += iStart - iPtrEnd; nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr; iSize = iEnd - iPtr;
iStart = iPtr; iStart = iPtr;
} }
} }
if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
data[hdr+7] -= nFrag; data[hdr+7] -= nFrag;
} }
if( iStart==get2byte(&data[hdr+5]) ){ if( iStart==get2byte(&data[hdr+5]) ){
/* The new freeblock is at the beginning of the cell content area, /* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another ** so just extend the cell content area rather than create another
** freelist entry */ ** freelist entry */
if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT; if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
put2byte(&data[hdr+1], iFreeBlk); put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd); put2byte(&data[hdr+5], iEnd);
}else{ }else{
@@ -1765,7 +1767,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
}else{ }else{
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
** an error. */ ** an error. */
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
pPage->max1bytePayload = pBt->max1bytePayload; pPage->max1bytePayload = pBt->max1bytePayload;
return SQLITE_OK; return SQLITE_OK;
@@ -1805,7 +1807,9 @@ static int btreeInitPage(MemPage *pPage){
data = pPage->aData; data = pPage->aData;
/* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
** the b-tree page type. */ ** the b-tree page type. */
if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; if( decodeFlags(pPage, data[hdr]) ){
return SQLITE_CORRUPT_PGNO(pPage->pgno);
}
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->maskPage = (u16)(pBt->pageSize - 1);
pPage->nOverflow = 0; pPage->nOverflow = 0;
@@ -1823,7 +1827,7 @@ static int btreeInitPage(MemPage *pPage){
pPage->nCell = get2byte(&data[hdr+3]); pPage->nCell = get2byte(&data[hdr+3]);
if( pPage->nCell>MX_CELL(pBt) ){ if( pPage->nCell>MX_CELL(pBt) ){
/* To many cells for a single page. The page must be corrupt */ /* To many cells for a single page. The page must be corrupt */
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
testcase( pPage->nCell==MX_CELL(pBt) ); testcase( pPage->nCell==MX_CELL(pBt) );
/* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
@@ -1851,12 +1855,12 @@ static int btreeInitPage(MemPage *pPage){
testcase( pc==iCellFirst ); testcase( pc==iCellFirst );
testcase( pc==iCellLast ); testcase( pc==iCellLast );
if( pc<iCellFirst || pc>iCellLast ){ if( pc<iCellFirst || pc>iCellLast ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
sz = pPage->xCellSize(pPage, &data[pc]); sz = pPage->xCellSize(pPage, &data[pc]);
testcase( pc+sz==usableSize ); testcase( pc+sz==usableSize );
if( pc+sz>usableSize ){ if( pc+sz>usableSize ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
} }
if( !pPage->leaf ) iCellLast++; if( !pPage->leaf ) iCellLast++;
@@ -1874,11 +1878,12 @@ static int btreeInitPage(MemPage *pPage){
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock. ** always be at least one cell before the first freeblock.
*/ */
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
while( 1 ){ while( 1 ){
if( pc>iCellLast ){ if( pc>iCellLast ){
return SQLITE_CORRUPT_BKPT; /* Freeblock off the end of the page */ /* Freeblock off the end of the page */
return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
next = get2byte(&data[pc]); next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]); size = get2byte(&data[pc+2]);
@@ -1887,10 +1892,12 @@ static int btreeInitPage(MemPage *pPage){
pc = next; pc = next;
} }
if( next>0 ){ if( next>0 ){
return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */ /* Freeblock not in ascending order */
return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
if( pc+size>(unsigned int)usableSize ){ if( pc+size>(unsigned int)usableSize ){
return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */ /* Last freeblock extends past page end */
return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
} }
@@ -1902,7 +1909,7 @@ static int btreeInitPage(MemPage *pPage){
** area, according to the page header, lies within the page. ** area, according to the page header, lies within the page.
*/ */
if( nFree>usableSize ){ if( nFree>usableSize ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
pPage->nFree = (u16)(nFree - iCellFirst); pPage->nFree = (u16)(nFree - iCellFirst);
pPage->isInit = 1; pPage->isInit = 1;
@@ -2069,7 +2076,7 @@ static int getAndInitPage(
/* If obtaining a child page for a cursor, we must verify that the page is /* If obtaining a child page for a cursor, we must verify that the page is
** compatible with the root page. */ ** compatible with the root page. */
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(pgno);
releasePage(*ppPage); releasePage(*ppPage);
goto getAndInitPage_error; goto getAndInitPage_error;
} }
@@ -3400,7 +3407,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW2 ){ if( eType==PTRMAP_OVERFLOW2 ){
/* The pointer is always the first 4 bytes of the page in this case. */ /* The pointer is always the first 4 bytes of the page in this case. */
if( get4byte(pPage->aData)!=iFrom ){ if( get4byte(pPage->aData)!=iFrom ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
put4byte(pPage->aData, iTo); put4byte(pPage->aData, iTo);
}else{ }else{
@@ -3419,7 +3426,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
pPage->xParseCell(pPage, pCell, &info); pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload ){ if( info.nLocal<info.nPayload ){
if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){ if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
if( iFrom==get4byte(pCell+info.nSize-4) ){ if( iFrom==get4byte(pCell+info.nSize-4) ){
put4byte(pCell+info.nSize-4, iTo); put4byte(pCell+info.nSize-4, iTo);
@@ -3437,7 +3444,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( i==nCell ){ if( i==nCell ){
if( eType!=PTRMAP_BTREE || if( eType!=PTRMAP_BTREE ||
get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
} }
@@ -4545,7 +4552,7 @@ static int accessPayload(
** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
** but is recast into its current form to avoid integer overflow problems ** but is recast into its current form to avoid integer overflow problems
*/ */
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
/* Check if data must be read/written to/from the btree page itself. */ /* Check if data must be read/written to/from the btree page itself. */
@@ -4692,7 +4699,8 @@ static int accessPayload(
} }
if( rc==SQLITE_OK && amt>0 ){ if( rc==SQLITE_OK && amt>0 ){
return SQLITE_CORRUPT_BKPT; /* Overflow chain ends prematurely */ /* Overflow chain ends prematurely */
return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
return rc; return rc;
} }
@@ -4958,7 +4966,7 @@ static int moveToRoot(BtCursor *pCur){
** (or the freelist). */ ** (or the freelist). */
assert( pRoot->intKey==1 || pRoot->intKey==0 ); assert( pRoot->intKey==1 || pRoot->intKey==0 );
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
} }
skip_init: skip_init:
@@ -5231,7 +5239,9 @@ int sqlite3BtreeMovetoUnpacked(
pCell = findCellPastPtr(pPage, idx); pCell = findCellPastPtr(pPage, idx);
if( pPage->intKeyLeaf ){ if( pPage->intKeyLeaf ){
while( 0x80 <= *(pCell++) ){ while( 0x80 <= *(pCell++) ){
if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; if( pCell>=pPage->aDataEnd ){
return SQLITE_CORRUPT_PGNO(pPage->pgno);
}
} }
} }
getVarint(pCell, (u64*)&nCellKey); getVarint(pCell, (u64*)&nCellKey);
@@ -5304,7 +5314,7 @@ int sqlite3BtreeMovetoUnpacked(
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */ testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 ){ if( nCell<2 ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(pPage->pgno);
goto moveto_finish; goto moveto_finish;
} }
pCellKey = sqlite3Malloc( nCell+18 ); pCellKey = sqlite3Malloc( nCell+18 );
@@ -5706,7 +5716,7 @@ static int allocateBtreePage(
} }
testcase( iTrunk==mxPage ); testcase( iTrunk==mxPage );
if( iTrunk>mxPage || nSearch++ > n ){ if( iTrunk>mxPage || nSearch++ > n ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(pPrevTrunk->pgno);
}else{ }else{
rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0); rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
} }
@@ -5735,7 +5745,7 @@ static int allocateBtreePage(
TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
}else if( k>(u32)(pBt->usableSize/4 - 2) ){ }else if( k>(u32)(pBt->usableSize/4 - 2) ){
/* Value of k is out of range. Database corruption */ /* Value of k is out of range. Database corruption */
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page; goto end_allocate_page;
#ifndef SQLITE_OMIT_AUTOVACUUM #ifndef SQLITE_OMIT_AUTOVACUUM
}else if( searchList }else if( searchList
@@ -5769,7 +5779,7 @@ static int allocateBtreePage(
MemPage *pNewTrunk; MemPage *pNewTrunk;
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
if( iNewTrunk>mxPage ){ if( iNewTrunk>mxPage ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page; goto end_allocate_page;
} }
testcase( iNewTrunk==mxPage ); testcase( iNewTrunk==mxPage );
@@ -5834,7 +5844,7 @@ static int allocateBtreePage(
iPage = get4byte(&aData[8+closest*4]); iPage = get4byte(&aData[8+closest*4]);
testcase( iPage==mxPage ); testcase( iPage==mxPage );
if( iPage>mxPage ){ if( iPage>mxPage ){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page; goto end_allocate_page;
} }
testcase( iPage==mxPage ); testcase( iPage==mxPage );
@@ -6104,7 +6114,8 @@ static int clearCell(
return SQLITE_OK; /* No overflow pages. Return without doing anything */ return SQLITE_OK; /* No overflow pages. Return without doing anything */
} }
if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){ if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */ /* Cell extends past end of page */
return SQLITE_CORRUPT_PGNO(pPage->pgno);
} }
ovflPgno = get4byte(pCell + pInfo->nSize - 4); ovflPgno = get4byte(pCell + pInfo->nSize - 4);
assert( pBt->usableSize > 4 ); assert( pBt->usableSize > 4 );

View File

@@ -3338,6 +3338,12 @@ int sqlite3CantopenError(int lineno){
return reportError(SQLITE_CANTOPEN, lineno, "cannot open file"); return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
} }
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
char zMsg[100];
sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
testcase( sqlite3GlobalConfig.xLog!=0 );
return reportError(SQLITE_CORRUPT, lineno, zMsg);
}
int sqlite3NomemError(int lineno){ int sqlite3NomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 ); testcase( sqlite3GlobalConfig.xLog!=0 );
return reportError(SQLITE_NOMEM, lineno, "OOM"); return reportError(SQLITE_NOMEM, lineno, "OOM");

View File

@@ -3402,11 +3402,14 @@ int sqlite3CantopenError(int);
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
int sqlite3NomemError(int); int sqlite3NomemError(int);
int sqlite3IoerrnomemError(int); int sqlite3IoerrnomemError(int);
int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__) # define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__) # define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else #else
# define SQLITE_NOMEM_BKPT SQLITE_NOMEM # define SQLITE_NOMEM_BKPT SQLITE_NOMEM
# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM # define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
#endif #endif
/* /*