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

Handle a few obscure problems that could manifest if a database corrupted in a certain way was written by a connection in the middle of a SELECT statement on the same db.

FossilOrigin-Name: eba8a564e62f84a9620008beead80081fe90a1b7
This commit is contained in:
dan
2014-01-20 18:25:44 +00:00
parent c25e2ebc01
commit 7df42aba12
4 changed files with 176 additions and 26 deletions

View File

@@ -3754,7 +3754,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
#define assertCellInfo(x)
@@ -4390,26 +4390,24 @@ static int moveToRoot(BtCursor *pCur){
return rc;
}
pCur->iPage = 0;
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
** NULL, the caller expects a table b-tree. If this is not the case,
** return an SQLITE_CORRUPT error. */
assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
return SQLITE_CORRUPT_BKPT;
}
}
/* Assert that the root page is of the correct type. This must be the
** case as the call to this function that loaded the root-page (either
** this call or a previous invocation) would have detected corruption
** if the assumption were not true, and it is not possible for the flags
** byte to have been modified while this cursor is holding a reference
** to the page. */
pRoot = pCur->apPage[0];
assert( pRoot->pgno==pCur->pgnoRoot );
assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
** NULL, the caller expects a table b-tree. If this is not the case,
** return an SQLITE_CORRUPT error.
**
** Earlier versions of SQLite assumed that this test could not fail
** if the root page was already loaded when this function was called (i.e.
** if pCur->iPage>=0). But this is not so if the database is corrupted
** in such a way that page pRoot is linked into a second b-tree table
** (or the freelist). */
assert( pRoot->intKey==1 || pRoot->intKey==0 );
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
return SQLITE_CORRUPT_BKPT;
}
pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
@@ -5251,6 +5249,7 @@ end_allocate_page:
if( rc==SQLITE_OK ){
if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
releasePage(*ppPage);
*ppPage = 0;
return SQLITE_CORRUPT_BKPT;
}
(*ppPage)->isInit = 0;