Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Add a new sqlite3_test_control() that indicates that database files are always well-formed. Use this during testing to enable assert() statements that prove conditions that are always true for well-formed databases. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 15e4f63d1f3cbcd0aa789fd3e460cd6e |
User & Date: | drh 2013-11-29 15:06:27 |
2013-11-29
| ||
15:39 | Change the name of the CORRUPTIBLE macro to CORRUPT_DB. check-in: f865be10 user: drh tags: trunk | |
15:06 | Add a new sqlite3_test_control() that indicates that database files are always well-formed. Use this during testing to enable assert() statements that prove conditions that are always true for well-formed databases. check-in: 15e4f63d user: drh tags: trunk | |
2013-11-28
| ||
19:28 | Update a few test cases to account for the new error message formats. check-in: 65a5bce3 user: dan tags: trunk | |
Changes to src/global.c.
144 144 SQLITE_WSD struct Sqlite3Config sqlite3Config = { 145 145 SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 146 146 1, /* bCoreMutex */ 147 147 SQLITE_THREADSAFE==1, /* bFullMutex */ 148 148 SQLITE_USE_URI, /* bOpenUri */ 149 149 SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 150 150 0x7ffffffe, /* mxStrlen */ 151 + 0, /* neverCorrupt */ 151 152 128, /* szLookaside */ 152 153 500, /* nLookaside */ 153 154 {0,0,0,0,0,0,0,0}, /* m */ 154 155 {0,0,0,0,0,0,0,0,0}, /* mutex */ 155 156 {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ 156 157 (void*)0, /* pHeap */ 157 158 0, /* nHeap */ ................................................................................ 178 179 0, /* pLogArg */ 179 180 0, /* bLocaltimeFault */ 180 181 #ifdef SQLITE_ENABLE_SQLLOG 181 182 0, /* xSqllog */ 182 183 0 /* pSqllogArg */ 183 184 #endif 184 185 }; 185 - 186 186 187 187 /* 188 188 ** Hash table for global functions - functions common to all 189 189 ** database connections. After initialization, this table is 190 190 ** read-only. 191 191 */ 192 192 SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
Changes to src/main.c.
3291 3291 case SQLITE_TESTCTRL_EXPLAIN_STMT: { 3292 3292 sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*); 3293 3293 const char **pzRet = va_arg(ap, const char**); 3294 3294 *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt); 3295 3295 break; 3296 3296 } 3297 3297 #endif 3298 + 3299 + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); 3300 + ** 3301 + ** Set or clear a flag that indicates that the database file is always well- 3302 + ** formed and never corrupt. This flag is clear by default, indicating that 3303 + ** database files might have arbitrary corruption. Setting the flag during 3304 + ** testing causes certain assert() statements in the code to be activated 3305 + ** that demonstrat invariants on well-formed database files. 3306 + */ 3307 + case SQLITE_TESTCTRL_NEVER_CORRUPT: { 3308 + sqlite3Config.neverCorrupt = va_arg(ap, int); 3309 + break; 3310 + } 3298 3311 3299 3312 } 3300 3313 va_end(ap); 3301 3314 #endif /* SQLITE_OMIT_BUILTIN_TEST */ 3302 3315 return rc; 3303 3316 } 3304 3317
Changes to src/sqlite.h.in.
6065 6065 #define SQLITE_TESTCTRL_ALWAYS 13 6066 6066 #define SQLITE_TESTCTRL_RESERVE 14 6067 6067 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 6068 6068 #define SQLITE_TESTCTRL_ISKEYWORD 16 6069 6069 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 6070 6070 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 6071 6071 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 6072 -#define SQLITE_TESTCTRL_LAST 19 6072 +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 6073 +#define SQLITE_TESTCTRL_LAST 20 6073 6074 6074 6075 /* 6075 6076 ** CAPI3REF: SQLite Runtime Status 6076 6077 ** 6077 6078 ** ^This interface is used to retrieve runtime status information 6078 6079 ** about the performance of SQLite, and optionally to reset various 6079 6080 ** highwater marks. ^The first argument is an integer code for
Changes to src/sqliteInt.h.
2534 2534 struct Sqlite3Config { 2535 2535 int bMemstat; /* True to enable memory status */ 2536 2536 int bCoreMutex; /* True to enable core mutexing */ 2537 2537 int bFullMutex; /* True to enable full mutexing */ 2538 2538 int bOpenUri; /* True to interpret filenames as URIs */ 2539 2539 int bUseCis; /* Use covering indices for full-scans */ 2540 2540 int mxStrlen; /* Maximum string length */ 2541 + int neverCorrupt; /* Database is always well-formed */ 2541 2542 int szLookaside; /* Default lookaside buffer size */ 2542 2543 int nLookaside; /* Default lookaside buffer count */ 2543 2544 sqlite3_mem_methods m; /* Low-level memory allocation interface */ 2544 2545 sqlite3_mutex_methods mutex; /* Low-level mutex interface */ 2545 2546 sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ 2546 2547 void *pHeap; /* Heap storage space */ 2547 2548 int nHeap; /* Size of pHeap[] */ ................................................................................ 2570 2571 int bLocaltimeFault; /* True to fail localtime() calls */ 2571 2572 #ifdef SQLITE_ENABLE_SQLLOG 2572 2573 void(*xSqllog)(void*,sqlite3*,const char*, int); 2573 2574 void *pSqllogArg; 2574 2575 #endif 2575 2576 }; 2576 2577 2578 +/* 2579 +** This macro is used inside of assert() statements to indicate that 2580 +** the assert is only valid on a well-formed database. Instead of: 2581 +** 2582 +** assert( X ); 2583 +** 2584 +** One writes: 2585 +** 2586 +** assert( X || CORRUPTIBLE ); 2587 +** 2588 +** CORRUPTIBLE is true during normal operation. But for many test cases, 2589 +** it is set to false using a sqlite3_test_control(). This enables assert() 2590 +** statements to prove things that are always true for well-formed 2591 +** databases. 2592 +*/ 2593 +#define CORRUPTIBLE (sqlite3Config.neverCorrupt==0) 2594 + 2577 2595 /* 2578 2596 ** Context pointer passed down through the tree-walk. 2579 2597 */ 2580 2598 struct Walker { 2581 2599 int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ 2582 2600 int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ 2583 2601 Parse *pParse; /* Parser context. */
Changes to src/test1.c.
5448 5448 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 5449 5449 int objc, /* Number of arguments */ 5450 5450 Tcl_Obj *CONST objv[] /* Command arguments */ 5451 5451 ){ 5452 5452 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET); 5453 5453 return TCL_OK; 5454 5454 } 5455 + 5456 +/* 5457 +** tclcmd: database_may_be_corrupt 5458 +** 5459 +** Indicate that database files might be corrupt. In other words, set the normal 5460 +** state of operation. 5461 +*/ 5462 +static int database_may_be_corrupt( 5463 + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 5464 + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 5465 + int objc, /* Number of arguments */ 5466 + Tcl_Obj *CONST objv[] /* Command arguments */ 5467 +){ 5468 + sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0); 5469 + return TCL_OK; 5470 +} 5471 +/* 5472 +** tclcmd: database_never_corrupt 5473 +** 5474 +** Indicate that database files are always well-formed. This enables extra assert() 5475 +** statements that test conditions that are always true for well-formed databases. 5476 +*/ 5477 +static int database_never_corrupt( 5478 + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 5479 + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 5480 + int objc, /* Number of arguments */ 5481 + Tcl_Obj *CONST objv[] /* Command arguments */ 5482 +){ 5483 + sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1); 5484 + return TCL_OK; 5485 +} 5455 5486 5456 5487 /* 5457 5488 ** tclcmd: pcache_stats 5458 5489 */ 5459 5490 static int test_pcache_stats( 5460 5491 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 5461 5492 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ ................................................................................ 6327 6358 { "sqlite3_enable_load_extension", test_enable_load, 0}, 6328 6359 { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, 6329 6360 { "sqlite3_limit", test_limit, 0}, 6330 6361 6331 6362 { "save_prng_state", save_prng_state, 0 }, 6332 6363 { "restore_prng_state", restore_prng_state, 0 }, 6333 6364 { "reset_prng_state", reset_prng_state, 0 }, 6365 + { "database_never_corrupt", database_never_corrupt, 0}, 6366 + { "database_may_be_corrupt", database_may_be_corrupt, 0}, 6334 6367 { "optimization_control", optimization_control,0}, 6335 6368 #if SQLITE_OS_WIN 6336 6369 { "lock_win32_file", win32_file_lock, 0 }, 6337 6370 { "exists_win32_path", win32_exists_path, 0 }, 6338 6371 { "find_win32_file", win32_find_file, 0 }, 6339 6372 { "delete_win32_file", win32_delete_file, 0 }, 6340 6373 { "make_win32_dir", win32_mkdir, 0 },
Changes to src/vdbeaux.c.
3108 3108 ** impact, since this routine is a very high runner. And so, we choose 3109 3109 ** to ignore the compiler warnings and leave this variable uninitialized. 3110 3110 */ 3111 3111 /* mem1.u.i = 0; // not needed, here to silence compiler warning */ 3112 3112 3113 3113 idx1 = getVarint32(aKey1, szHdr1); 3114 3114 d1 = szHdr1; 3115 - assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); 3115 + assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPTIBLE ); 3116 3116 assert( pKeyInfo->aSortOrder!=0 ); 3117 + assert( (idx1<=szHdr1 && i<pPKey2->nField) || CORRUPTIBLE ); 3117 3118 do{ 3118 3119 u32 serial_type1; 3119 3120 3120 3121 /* Read the serial types for the next element in each key. */ 3121 3122 idx1 += getVarint32( aKey1+idx1, serial_type1 ); 3122 3123 3123 3124 /* Verify that there is enough key space remaining to avoid
Changes to test/corrupt.test.
20 20 set testdir [file dirname $argv0] 21 21 source $testdir/tester.tcl 22 22 23 23 # Do not use a codec for tests in this file, as the database file is 24 24 # manipulated directly using tcl scripts (using the [hexio_write] command). 25 25 # 26 26 do_not_use_codec 27 + 28 +# These tests deal with corrupt database files 29 +# 30 +database_may_be_corrupt 27 31 28 32 # Construct a large database for testing. 29 33 # 30 34 do_test corrupt-1.1 { 31 35 execsql { 32 36 BEGIN; 33 37 CREATE TABLE t1(x);
Changes to test/corrupt2.test.
18 18 set testdir [file dirname $argv0] 19 19 source $testdir/tester.tcl 20 20 21 21 # Do not use a codec for tests in this file, as the database file is 22 22 # manipulated directly using tcl scripts (using the [hexio_write] command). 23 23 # 24 24 do_not_use_codec 25 + 26 +# These tests deal with corrupt database files 27 +# 28 +database_may_be_corrupt 25 29 26 30 set presql "" 27 31 catch { set presql "$::G(perm:presql);" } 28 32 unset -nocomplain ::G(perm:presql) 29 33 30 34 # The following tests - corrupt2-1.* - create some databases corrupted in 31 35 # specific ways and ensure that SQLite detects them as corrupt.
Changes to test/corrupt3.test.
18 18 set testdir [file dirname $argv0] 19 19 source $testdir/tester.tcl 20 20 21 21 # Do not use a codec for tests in this file, as the database file is 22 22 # manipulated directly using tcl scripts (using the [hexio_write] command). 23 23 # 24 24 do_not_use_codec 25 + 26 +# These tests deal with corrupt database files 27 +# 28 +database_may_be_corrupt 25 29 26 30 # We must have the page_size pragma for these tests to work. 27 31 # 28 32 ifcapable !pager_pragmas||direct_read { 29 33 finish_test 30 34 return 31 35 }
Changes to test/corrupt4.test.
18 18 set testdir [file dirname $argv0] 19 19 source $testdir/tester.tcl 20 20 21 21 # Do not use a codec for tests in this file, as the database file is 22 22 # manipulated directly using tcl scripts (using the [hexio_write] command). 23 23 # 24 24 do_not_use_codec 25 + 26 +# These tests deal with corrupt database files 27 +# 28 +database_may_be_corrupt 25 29 26 30 # We must have the page_size pragma for these tests to work. 27 31 # 28 32 ifcapable !pager_pragmas { 29 33 finish_test 30 34 return 31 35 }
Changes to test/corrupt5.test.
14 14 # segfault if it sees a corrupt database file. Checks for 15 15 # malformed schema. 16 16 # 17 17 # $Id: corrupt5.test,v 1.3 2009/06/04 02:47:04 shane Exp $ 18 18 19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 + 22 +# These tests deal with corrupt database files 23 +# 24 +database_may_be_corrupt 21 25 22 26 # We must have the page_size pragma for these tests to work. 23 27 # 24 28 ifcapable !pager_pragmas { 25 29 finish_test 26 30 return 27 31 }
Changes to test/corrupt6.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 # We must have the page_size pragma for these tests to work. 28 32 # 29 33 ifcapable !pager_pragmas { 30 34 finish_test 31 35 return 32 36 }
Changes to test/corrupt7.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 # We must have the page_size pragma for these tests to work. 28 32 # 29 33 ifcapable !pager_pragmas { 30 34 finish_test 31 35 return 32 36 }
Changes to test/corrupt8.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 # We must have the page_size pragma for these tests to work. 28 32 # 29 33 ifcapable !pager_pragmas||!autovacuum { 30 34 finish_test 31 35 return 32 36 }
Changes to test/corrupt9.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 # We must have the page_size pragma for these tests to work. 28 32 # 29 33 ifcapable !pager_pragmas { 30 34 finish_test 31 35 return 32 36 }
Changes to test/corruptA.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 28 32 # Create a database to work with. 29 33 # 30 34 do_test corruptA-1.1 { 31 35 execsql { 32 36 CREATE TABLE t1(x);
Changes to test/corruptB.test.
25 25 set testdir [file dirname $argv0] 26 26 source $testdir/tester.tcl 27 27 28 28 # Do not use a codec for tests in this file, as the database file is 29 29 # manipulated directly using tcl scripts (using the [hexio_write] command). 30 30 # 31 31 do_not_use_codec 32 + 33 +# These tests deal with corrupt database files 34 +# 35 +database_may_be_corrupt 32 36 33 37 34 38 do_test corruptB-1.1 { 35 39 execsql { 36 40 PRAGMA auto_vacuum = 1; 37 41 CREATE TABLE t1(x); 38 42 INSERT INTO t1 VALUES(randomblob(200));
Changes to test/corruptC.test.
22 22 set testdir [file dirname $argv0] 23 23 source $testdir/tester.tcl 24 24 25 25 # Do not use a codec for tests in this file, as the database file is 26 26 # manipulated directly using tcl scripts (using the [hexio_write] command). 27 27 # 28 28 do_not_use_codec 29 + 30 +# These tests deal with corrupt database files 31 +# 32 +database_may_be_corrupt 29 33 30 34 # Construct a compact, dense database for testing. 31 35 # 32 36 do_test corruptC-1.1 { 33 37 execsql { 34 38 PRAGMA auto_vacuum = 0; 35 39 PRAGMA legacy_file_format=1;
Changes to test/corruptD.test.
14 14 set testdir [file dirname $argv0] 15 15 source $testdir/tester.tcl 16 16 17 17 # Do not use a codec for tests in this file, as the database file is 18 18 # manipulated directly using tcl scripts (using the [hexio_write] command). 19 19 # 20 20 do_not_use_codec 21 + 22 +# These tests deal with corrupt database files 23 +# 24 +database_may_be_corrupt 21 25 22 26 #-------------------------------------------------------------------------- 23 27 # OVERVIEW 24 28 # 25 29 # This test file attempts to verify that SQLite does not read past the 26 30 # end of any in-memory buffers as a result of corrupted database page 27 31 # images. Usually this happens because a field within a database page
Changes to test/corruptE.test.
19 19 set testdir [file dirname $argv0] 20 20 source $testdir/tester.tcl 21 21 22 22 # Do not use a codec for tests in this file, as the database file is 23 23 # manipulated directly using tcl scripts (using the [hexio_write] command). 24 24 # 25 25 do_not_use_codec 26 + 27 +# These tests deal with corrupt database files 28 +# 29 +database_may_be_corrupt 26 30 27 31 # Do not run the tests in this file if ENABLE_OVERSIZE_CELL_CHECK is on. 28 32 # 29 33 ifcapable oversize_cell_check { 30 34 finish_test 31 35 return 32 36 }
Changes to test/corruptF.test.
14 14 source $testdir/tester.tcl 15 15 set testprefix corruptF 16 16 17 17 # Do not use a codec for tests in this file, as the database file is 18 18 # manipulated directly using tcl scripts (using the [hexio_write] command). 19 19 # 20 20 do_not_use_codec 21 + 22 +# These tests deal with corrupt database files 23 +# 24 +database_may_be_corrupt 21 25 22 26 proc str {i} { format %08d $i } 23 27 24 28 # Create a 6 page database containing a single table - t1. Table t1 25 29 # consists of page 2 (the root page) and pages 5 and 6 (leaf pages). 26 30 # Database pages 3 and 4 are on the free list. 27 31 #
Changes to test/corruptG.test.
14 14 source $testdir/tester.tcl 15 15 set testprefix corruptG 16 16 17 17 # Do not use a codec for tests in this file, as the database file is 18 18 # manipulated directly using tcl scripts (using the [hexio_write] command). 19 19 # 20 20 do_not_use_codec 21 + 22 +# These tests deal with corrupt database files 23 +# 24 +database_may_be_corrupt 21 25 22 26 # Create a simple database with a single entry. Then corrupt the 23 27 # header-size varint on the index payload so that it maps into a 24 28 # negative number. Try to use the database. 25 29 # 26 30 27 31 do_execsql_test 1.1 {
Changes to test/tester.tcl.
1881 1881 1882 1882 # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set 1883 1883 # to non-zero, then set the global variable $AUTOVACUUM to 1. 1884 1884 set AUTOVACUUM $sqlite_options(default_autovacuum) 1885 1885 1886 1886 # Make sure the FTS enhanced query syntax is disabled. 1887 1887 set sqlite_fts3_enable_parentheses 0 1888 + 1889 +# During testing, assume that all database files are well-formed. The 1890 +# few test cases that deliberately corrupt database files should rescind 1891 +# this setting by invoking "database_can_be_corrupt" 1892 +# 1893 +database_never_corrupt 1888 1894 1889 1895 source $testdir/thread_common.tcl 1890 1896 source $testdir/malloc_common.tcl