Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a case where database corruption was causing an invalid reference. (CVS 5484) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7aecabacf924ad8c1f9f4e707d0c56e4 |
User & Date: | danielk1977 2008-07-26 18:26:10.000 |
Context
2008-07-26
| ||
18:47 | Remove a branch that could not be taken from OP_IsUnique. (CVS 5485) (check-in: 75c2a532f4 user: danielk1977 tags: trunk) | |
18:26 | Fix a case where database corruption was causing an invalid reference. (CVS 5484) (check-in: 7aecabacf9 user: danielk1977 tags: trunk) | |
2008-07-25
| ||
16:39 | Add an SQLITE_OMIT_LOCALTIME around the "utc" modifier in date/time functions. (CVS 5483) (check-in: 71486e93b2 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.764 2008/07/26 18:26:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
3132 3133 3134 3135 3136 3137 3138 | /* Make sure K is a string and make zKey point to K */ assert( pK->flags & MEM_Blob ); zKey = pK->z; nKey = pK->n; | | > > > | 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 | /* Make sure K is a string and make zKey point to K */ assert( pK->flags & MEM_Blob ); zKey = pK->z; nKey = pK->n; rc = sqlite3VdbeIdxRowidLen((u8*)zKey, nKey, &szRowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } len = nKey-szRowid; /* Search for an entry in P1 where all but the last four bytes match K. ** If there is no such entry, jump immediately to P2. */ assert( pCx->deferredMoveto==0 ); pCx->cacheStatus = CACHE_STALE; |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** ** $Id: vdbeInt.h,v 1.150 2008/07/26 18:26:10 danielk1977 Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ /* ** intToKey() and keyToInt() used to transform the rowid. But with ** the latest versions of the design they are no-ops. |
︙ | ︙ | |||
386 387 388 389 390 391 392 | int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*,UnpackedRecord *,int,const unsigned char*,int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); | | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*,UnpackedRecord *,int,const unsigned char*,int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeIdxRowidLen(const u8*, int, int*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); int sqlite3VdbeMemTooBig(Mem*); int sqlite3VdbeMemCopy(Mem*, const Mem*); void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.400 2008/07/26 18:26:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" |
︙ | ︙ | |||
2350 2351 2352 2353 2354 2355 2356 | /* ** The argument is an index entry composed using the OP_MakeRecord opcode. ** The last entry in this record should be an integer (specifically ** an integer rowid). This routine returns the number of bytes in ** that integer. */ | | > > > | > | 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | /* ** The argument is an index entry composed using the OP_MakeRecord opcode. ** The last entry in this record should be an integer (specifically ** an integer rowid). This routine returns the number of bytes in ** that integer. */ int sqlite3VdbeIdxRowidLen(const u8 *aKey, int nKey, int *pRowidLen){ u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ (void)getVarint32(aKey, szHdr); if( szHdr>nKey ){ return SQLITE_CORRUPT_BKPT; } (void)getVarint32(&aKey[szHdr-1], typeRowid); *pRowidLen = sqlite3VdbeSerialTypeLen(typeRowid); return SQLITE_OK; } /* ** pCur points at an index entry created using the OP_MakeRecord opcode. ** Read the rowid (the last field in the record) and store it in *rowid. ** Return SQLITE_OK if everything works, or an error code otherwise. |
︙ | ︙ | |||
2425 2426 2427 2428 2429 2430 2431 | if( nCellKey<=0 ){ *res = 0; return SQLITE_OK; } m.db = 0; m.flags = 0; m.zMalloc = 0; | | > | < | 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 | if( nCellKey<=0 ){ *res = 0; return SQLITE_OK; } m.db = 0; m.flags = 0; m.zMalloc = 0; if( (rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m)) || (rc = sqlite3VdbeIdxRowidLen((u8*)m.z, m.n, &lenRowid)) ){ return rc; } if( !pUnpacked ){ pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey, zSpace, sizeof(zSpace)); }else{ pRec = pUnpacked; } if( pRec==0 ){ |
︙ | ︙ |
Changes to test/corrupt7.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 | #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. It specifically focuses # on corrupt cell offsets in a btree page. # | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. It specifically focuses # on corrupt cell offsets in a btree page. # # $Id: corrupt7.test,v 1.4 2008/07/26 18:26:10 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { |
︙ | ︙ | |||
68 69 70 71 72 73 74 75 | db close hexio_write test.db 1062 04 sqlite3 db test.db db eval {PRAGMA integrity_check(1)} } {{*** in database main *** Corruption detected in cell 15 on page 2}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | db close hexio_write test.db 1062 04 sqlite3 db test.db db eval {PRAGMA integrity_check(1)} } {{*** in database main *** Corruption detected in cell 15 on page 2}} do_test corrupt7-3.1 { execsql { DROP TABLE t1; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 'one'); INSERT INTO t1 VALUES(100, 'one hundred'); INSERT INTO t1 VALUES(100000, 'one hundred thousand'); CREATE INDEX i1 ON t1(b); } db close # Locate the 3rd cell in the index. set cell_offset [hexio_get_int [hexio_read test.db [expr 1024*2 + 12] 2]] incr cell_offset [expr 1024*2] incr cell_offset 1 # This write corrupts the "header-size" field of the database record # stored in the index cell. At one point this was causing sqlite to # reference invalid memory. hexio_write test.db $cell_offset FFFF7F sqlite3 db test.db catchsql { SELECT b FROM t1 WHERE b > 'o' AND b < 'p'; } } {1 {database disk image is malformed}} finish_test |