OLD | NEW |
(Empty) | |
| 1 # 2010 October 27 |
| 2 # |
| 3 # May you do good and not evil. |
| 4 # May you find forgiveness for yourself and forgive others. |
| 5 # May you share freely, never taking more than you give. |
| 6 # |
| 7 #*********************************************************************** |
| 8 # Test that the FTS3 extension does not crash when it encounters a |
| 9 # corrupt data structure on disk. |
| 10 # |
| 11 |
| 12 |
| 13 set testdir [file dirname $argv0] |
| 14 source $testdir/tester.tcl |
| 15 |
| 16 # If SQLITE_ENABLE_FTS3 is not defined, omit this file. |
| 17 ifcapable !fts3 { finish_test ; return } |
| 18 |
| 19 set ::testprefix fts3corrupt |
| 20 |
| 21 |
| 22 # Test that a doclist with a length field that indicates that the doclist |
| 23 # extends past the end of the node on which it resides is correctly identified |
| 24 # as database corruption. |
| 25 # |
| 26 do_execsql_test 1.0 { |
| 27 CREATE VIRTUAL TABLE t1 USING fts3; |
| 28 INSERT INTO t1 VALUES('hello'); |
| 29 } {} |
| 30 do_test fts3corrupt-1.1 { |
| 31 set blob [db one {SELECT root from t1_segdir}] |
| 32 set blob [binary format a7ca* $blob 24 [string range $blob 8 end]] |
| 33 execsql { UPDATE t1_segdir SET root = $blob } |
| 34 } {} |
| 35 do_test fts3corrupt-1.2 { |
| 36 foreach w {a b c d e f g h i j k l m n o} { |
| 37 execsql { INSERT INTO t1 VALUES($w) } |
| 38 } |
| 39 } {} |
| 40 do_catchsql_test 1.3 { |
| 41 INSERT INTO t1 VALUES('world'); |
| 42 } {1 {database disk image is malformed}} |
| 43 do_execsql_test 1.4 { |
| 44 DROP TABLE t1; |
| 45 } |
| 46 |
| 47 # This block of tests checks that corruption is correctly detected if the |
| 48 # length field of a term on a leaf node indicates that the term extends past |
| 49 # the end of the node on which it resides. There are two cases: |
| 50 # |
| 51 # 1. The first term on the node. |
| 52 # 2. The second or subsequent term on the node (prefix compressed term). |
| 53 # |
| 54 do_execsql_test 2.0 { |
| 55 CREATE VIRTUAL TABLE t1 USING fts3; |
| 56 BEGIN; |
| 57 INSERT INTO t1 VALUES('hello'); |
| 58 INSERT INTO t1 VALUES('hello'); |
| 59 INSERT INTO t1 VALUES('hello'); |
| 60 INSERT INTO t1 VALUES('hello'); |
| 61 INSERT INTO t1 VALUES('hello'); |
| 62 COMMIT; |
| 63 } {} |
| 64 do_test fts3corrupt-2.1 { |
| 65 set blob [db one {SELECT root from t1_segdir}] |
| 66 set blob [binary format a*a* "\x00\x7F" [string range $blob 2 end]] |
| 67 execsql { UPDATE t1_segdir SET root = $blob } |
| 68 } {} |
| 69 do_catchsql_test 2.2 { |
| 70 SELECT rowid FROM t1 WHERE t1 MATCH 'hello' |
| 71 } {1 {database disk image is malformed}} |
| 72 |
| 73 do_execsql_test 3.0 { |
| 74 DROP TABLE t1; |
| 75 CREATE VIRTUAL TABLE t1 USING fts3; |
| 76 BEGIN; |
| 77 INSERT INTO t1 VALUES('hello'); |
| 78 INSERT INTO t1 VALUES('world'); |
| 79 COMMIT; |
| 80 } {} |
| 81 do_test fts3corrupt-3.1 { |
| 82 set blob [db one {SELECT quote(root) from t1_segdir}] |
| 83 set blob [binary format a11a*a* $blob "\x7F" [string range $blob 12 end]] |
| 84 execsql { UPDATE t1_segdir SET root = $blob } |
| 85 } {} |
| 86 do_catchsql_test 3.2 { |
| 87 SELECT rowid FROM t1 WHERE t1 MATCH 'world' |
| 88 } {1 {database disk image is malformed}} |
| 89 |
| 90 |
| 91 do_execsql_test 4.0 { |
| 92 DROP TABLE t1; |
| 93 CREATE VIRTUAL TABLE t1 USING fts3; |
| 94 INSERT INTO t1(t1) VALUES('nodesize=24'); |
| 95 } |
| 96 do_test fts3corrupt-4.1 { |
| 97 execsql BEGIN |
| 98 foreach s { |
| 99 "amxtvoo adqwroyhz auq aithtir avniqnuynvf axp ahibayfynig agbicpm" |
| 100 "ajdtebs anteaxr aieynenwmd awpl alo akxcrwow aoxftge aoqvgul" |
| 101 "amcfvdr auz apu aebelm ahuxyz aqc asyafdb agulvhvqu" |
| 102 "apepwfyz azkhdvkw aenyelxzbk aslnitbyet aycdsdcpgr aqzzdbc agfi axnypydou" |
| 103 "aaqrzzcm apcxdxo atumltzj aevvivo aodknoft aqoyytoz alobx apldt" |
| 104 } { |
| 105 execsql { INSERT INTO t1 VALUES($s) } |
| 106 } |
| 107 execsql COMMIT |
| 108 } {} |
| 109 |
| 110 do_catchsql_test 4.2 { |
| 111 UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF'; |
| 112 SELECT rowid FROM t1 WHERE t1 MATCH 'world'; |
| 113 } {1 {database disk image is malformed}} |
| 114 |
| 115 set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \ |
| 116 22 120 [string repeat a 120] \ |
| 117 22 120 [string repeat b 120] \ |
| 118 22 120 [string repeat c 120] \ |
| 119 22 120 [string repeat d 120] \ |
| 120 22 120 [string repeat e 120] \ |
| 121 22 120 [string repeat f 120] \ |
| 122 22 120 [string repeat g 120] \ |
| 123 22 120 [string repeat h 120] \ |
| 124 22 120 [string repeat i 120] \ |
| 125 22 120 [string repeat j 120] \ |
| 126 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
| 127 ] |
| 128 |
| 129 do_catchsql_test 4.3 { |
| 130 UPDATE t1_segdir SET root = $blob; |
| 131 SELECT rowid FROM t1 WHERE t1 MATCH 'world'; |
| 132 } {1 {database disk image is malformed}} |
| 133 |
| 134 # Test a special kind of corruption, where the %_stat table contains |
| 135 # an invalid entry. At one point this could lead to a division-by-zero |
| 136 # error in fts4. |
| 137 # |
| 138 do_execsql_test 5.0 { |
| 139 DROP TABLE t1; |
| 140 CREATE VIRTUAL TABLE t1 USING fts4; |
| 141 } |
| 142 do_test 5.1 { |
| 143 db func nn nn |
| 144 execsql BEGIN |
| 145 execsql { INSERT INTO t1 VALUES('one') } |
| 146 execsql { INSERT INTO t1 VALUES('two') } |
| 147 execsql { INSERT INTO t1 VALUES('three') } |
| 148 execsql { INSERT INTO t1 VALUES('four') } |
| 149 execsql COMMIT |
| 150 } {} |
| 151 do_catchsql_test 5.2 { |
| 152 UPDATE t1_stat SET value = X'0000'; |
| 153 SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; |
| 154 } {1 {database disk image is malformed}} |
| 155 do_catchsql_test 5.3 { |
| 156 UPDATE t1_stat SET value = NULL; |
| 157 SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; |
| 158 } {1 {database disk image is malformed}} |
| 159 |
| 160 |
| 161 finish_test |
| 162 |
OLD | NEW |