Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Bug fix: Only trust the database size number at offset 28 if the change counter at offset 24 matches the version number counter at offset 92. This prevents corruption in the case of two applications writing to the database where one is an older version of SQLite and the other is a newer version. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f80c3f922a114e738613955a939db46c |
User & Date: | drh 2010-06-17 02:13:40.000 |
References
2010-06-17
| ||
06:19 | Merge fix [f80c3f922a] with experimental changes. (check-in: 20133e9ca9 user: dan tags: experimental) | |
Context
2010-06-17
| ||
10:24 | Add test case for [fc62af4523]. (check-in: cccd32c692 user: dan tags: trunk) | |
06:19 | Merge fix [f80c3f922a] with experimental changes. (check-in: 20133e9ca9 user: dan tags: experimental) | |
02:13 | Bug fix: Only trust the database size number at offset 28 if the change counter at offset 24 matches the version number counter at offset 92. This prevents corruption in the case of two applications writing to the database where one is an older version of SQLite and the other is a newer version. (check-in: f80c3f922a user: drh tags: trunk) | |
2010-06-16
| ||
12:30 | Add extra test cases to pager1.test. (check-in: ad3209572d user: dan tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
2246 2247 2248 2249 2250 2251 2252 | /* Do some checking to help insure the file we opened really is ** a valid database file. */ nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); if( (rc = sqlite3PagerPagecount(pBt->pPager, &nPageFile))!=SQLITE_OK ){; goto page1_init_failed; } | | | 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 | /* Do some checking to help insure the file we opened really is ** a valid database file. */ nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); if( (rc = sqlite3PagerPagecount(pBt->pPager, &nPageFile))!=SQLITE_OK ){; goto page1_init_failed; } if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ nPage = nPageFile; } if( nPage>0 ){ int pageSize; int usableSize; u8 *page1 = pPage1->aData; rc = SQLITE_NOTADB; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 | } if( pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy ** of bytes 24..39 of the database. Bytes 28..31 should always be | | | | | 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 | } if( pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy ** of bytes 24..39 of the database. Bytes 28..31 should always be ** zero or the size of the database in page. Bytes 32..35 and 35..39 ** should be page numbers which are never 0xffffffff. So filling ** pPager->dbFileVers[] with all 0xff bytes should suffice. ** ** For an encrypted database, the situation is more complex: bytes ** 24..39 of the database are white noise. But the probability of ** white noising equaling 16 bytes of 0xff is vanishingly small so ** we should still be ok. */ memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); |
︙ | ︙ | |||
4986 4987 4988 4989 4990 4991 4992 | if( rc==SQLITE_OK ){ /* Increment the value just read and write it back to byte 24. */ change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); change_counter++; put32bits(((char*)pPgHdr->pData)+24, change_counter); | | > > > | 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 | if( rc==SQLITE_OK ){ /* Increment the value just read and write it back to byte 24. */ change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); change_counter++; put32bits(((char*)pPgHdr->pData)+24, change_counter); /* Also store the SQLite version number in bytes 96..99 and in ** bytes 92..95 store the change counter for which the version number ** is valid. */ put32bits(((char*)pPgHdr->pData)+92, change_counter); put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER); /* If running in direct mode, write the contents of page 1 to the file. */ if( DIRECT_MODE ){ const void *zBuf = pPgHdr->pData; assert( pPager->dbFileSize>0 ); rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); |
︙ | ︙ |
Changes to tool/showdb.c.
︙ | ︙ | |||
165 166 167 168 169 170 171 | print_decode_line(aData, 64, 4, "Incremental-vacuum mode"); print_decode_line(aData, 68, 4, "meta[7]"); print_decode_line(aData, 72, 4, "meta[8]"); print_decode_line(aData, 76, 4, "meta[9]"); print_decode_line(aData, 80, 4, "meta[10]"); print_decode_line(aData, 84, 4, "meta[11]"); print_decode_line(aData, 88, 4, "meta[12]"); | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | print_decode_line(aData, 64, 4, "Incremental-vacuum mode"); print_decode_line(aData, 68, 4, "meta[7]"); print_decode_line(aData, 72, 4, "meta[8]"); print_decode_line(aData, 76, 4, "meta[9]"); print_decode_line(aData, 80, 4, "meta[10]"); print_decode_line(aData, 84, 4, "meta[11]"); print_decode_line(aData, 88, 4, "meta[12]"); print_decode_line(aData, 92, 4, "Change counter for version number"); print_decode_line(aData, 96, 4, "SQLite version number"); } /* ** Create a description for a single cell. */ static int describeCell(unsigned char cType, unsigned char *a, char **pzDesc){ |
︙ | ︙ |