Index: src/btInt.h ================================================================== --- src/btInt.h +++ src/btInt.h @@ -45,10 +45,12 @@ typedef struct BtDbhdr BtDbhdr; struct BtDbhdr { u32 pgsz; /* Page size in bytes */ u32 nPg; /* Number of pages in database */ u32 cookie; /* User cookie value (SQL schema cookie) */ + u32 padding; /* Unused */ + u32 aCksum[2]; /* Checksum over other fields */ }; /************************************************************************* ** Interface to bt_pager.c functionality. */ Index: src/bt_log.c ================================================================== --- src/bt_log.c +++ src/bt_log.c @@ -804,30 +804,46 @@ return btLogHashRollback(pLog, btLogFrameHash(pLog, iLast), iLast); } static int btLogReadDbhdr(BtLog *pLog, BtDbhdr *pHdr){ BtLock *p = pLog->pLock; - int rc; - i64 nByte; + int rc; /* Return code */ + i64 nByte; /* Size of database file in byte */ rc = p->pVfs->xSize(p->pFd, &nByte); if( rc==SQLITE4_OK && nByte>0 ){ rc = p->pVfs->xRead(p->pFd, 0, pHdr, sizeof(BtDbhdr)); - if( BTLOG_LITTLE_ENDIAN ){ - pHdr->cookie = BYTESWAP32(pHdr->cookie); - pHdr->nPg = BYTESWAP32(pHdr->nPg); - pHdr->pgsz = BYTESWAP32(pHdr->pgsz); - } - assert( pHdr->pgsz>0 ); - }else{ - memset(pHdr, 0, sizeof(BtDbhdr)); - pHdr->pgsz = BT_DEFAULT_PGSZ; - pHdr->nPg = 1; + if( rc==SQLITE4_OK ){ + u32 aCksum[2]; + btLogChecksum(1, pHdr, offsetof(BtDbhdr, aCksum), 0, aCksum); + if( aCksum[0]==pHdr->aCksum[0] && aCksum[1]==pHdr->aCksum[1] ){ + return SQLITE4_OK; + } + } } + memset(pHdr, 0, sizeof(BtDbhdr)); + pHdr->pgsz = BT_DEFAULT_PGSZ; + pHdr->nPg = 1; return rc; } + +static int btLogUpdateDbhdr(BtLog *pLog, u8 *aData){ + BtDbhdr dbhdr; + + dbhdr.cookie = pLog->snapshot.iCookie; + dbhdr.nPg = pLog->snapshot.nPg; + dbhdr.pgsz = pLog->snapshot.pgsz; + dbhdr.padding = 0; + btLogChecksum(1, &dbhdr, offsetof(BtDbhdr, aCksum), 0, dbhdr.aCksum); + + assert( dbhdr.pgsz>0 ); + memcpy(aData, &dbhdr, sizeof(BtDbhdr)); + + return SQLITE4_OK; +} + /* ** Run log recovery. In other words, read the log file from disk and ** initialize the shared-memory accordingly. */ @@ -1698,28 +1714,10 @@ + (int)pLog->snapshot.aLog[5] - (int)pLog->snapshot.aLog[4] + (pLog->snapshot.aLog[5]!=0) ; } -static int btLogUpdateDbhdr(BtLog *pLog, u8 *aData){ - BtDbhdr dbhdr; - - dbhdr.cookie = pLog->snapshot.iCookie; - dbhdr.nPg = pLog->snapshot.nPg; - dbhdr.pgsz = pLog->snapshot.pgsz; - - if( BTLOG_LITTLE_ENDIAN ){ - dbhdr.cookie = BYTESWAP32(dbhdr.cookie); - dbhdr.nPg = BYTESWAP32(dbhdr.nPg); - dbhdr.pgsz = BYTESWAP32(dbhdr.pgsz); - assert( dbhdr.pgsz>0 ); - } - memcpy(aData, &dbhdr, sizeof(BtDbhdr)); - - return SQLITE4_OK; -} - int sqlite4BtLogCheckpoint(BtLog *pLog, int nFrameBuffer){ BtLock *pLock = pLog->pLock; int rc; /* Take the CHECKPOINTER lock. */ Index: test/permutations.test ================================================================== --- test/permutations.test +++ test/permutations.test @@ -130,11 +130,10 @@ # quick # full # lappend ::testsuitelist xxx - # attach.test attach3.test # fkey2.test test_suite "bt" -prefix "" -description { } -files { simple3.test @@ -141,11 +140,11 @@ alter.test alter3.test alter4.test analyze.test analyze3.test analyze4.test analyze5.test analyze6.test analyze7.test analyze8.test auth.test auth2.test auth3.test auth4.test aggerror.test - attach4.test + attach.test attach3.test attach4.test autoindex1.test badutf.test badutf2.test between.test bigrow.test bind.test