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

Reformat WAL code for clearer presentation. Update comments for correctness.

Add checks to ensure that corruption in shared-memory does not result in
an infinite loop.

FossilOrigin-Name: 40eaada7ec45e70bdf64d060051f24c5c5e3faf3
This commit is contained in:
drh
2010-07-09 03:19:07 +00:00
parent a485cccd0a
commit 519426aaf8
3 changed files with 31 additions and 19 deletions

View File

@@ -495,14 +495,15 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32 *)*(iPage+1);
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM;
}
memset((void *)&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData));
memset((void*)&apNew[pWal->nWiData], 0,
sizeof(u32*)*(iPage+1-pWal->nWiData));
pWal->apWiData = apNew;
pWal->nWiData = iPage+1;
}
@@ -678,9 +679,10 @@ static int walDecodeFrame(
return 0;
}
/* A frame is only valid if a checksum of the first 16 bytes
** of the frame-header, and the frame-data matches
** the checksum in the last 8 bytes of the frame-header.
/* A frame is only valid if a checksum of the WAL header,
** all prior frams, the first 16 bytes of this frame-header,
** and the frame-data matches the checksum in the last 8
** bytes of this frame-header.
*/
nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
@@ -940,7 +942,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
if( rc==SQLITE_OK ){
int iKey; /* Hash table key */
int idx; /* Value to write to hash-table slot */
TESTONLY( int nCollide = 0; /* Number of hash collisions */ )
int nCollide; /* Number of hash collisions */
idx = iFrame - iZero;
assert( idx <= HASHTABLE_NSLOT/2 + 1 );
@@ -965,8 +967,9 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
}
/* Write the aPgno[] array entry and the hash-table slot. */
nCollide = idx;
for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
assert( nCollide++ < idx );
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
}
aPgno[idx] = iPage;
aHash[iKey] = (ht_slot)idx;
@@ -1452,7 +1455,11 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
ht_slot *aIndex; /* Sorted index for this segment */
aPgno++;
nEntry = (int)(((i+1)==nSegment)?(int)(iLast-iZero):(u32 *)aHash-(u32 *)aPgno);
if( (i+1)==nSegment ){
nEntry = (int)(iLast - iZero);
}else{
nEntry = (u32*)aHash - (u32*)aPgno;
}
aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
iZero++;
@@ -2089,18 +2096,23 @@ int sqlite3WalRead(
volatile u32 *aPgno; /* Pointer to array of page numbers */
u32 iZero; /* Frame number corresponding to aPgno[0] */
int iKey; /* Hash slot index */
int rc;
int nCollide; /* Number of hash collisions remaining */
int rc; /* Error code */
rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
u32 iFrame = aHash[iKey] + iZero;
if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
assert( iFrame>iRead );
iRead = iFrame;
}
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
}
}
}