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_test 1.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
44 do_execsql_test 1.4 { | |
45 DROP TABLE t1; | |
46 } | |
47 | |
48 # This block of tests checks that corruption is correctly detected if the | |
49 # length field of a term on a leaf node indicates that the term extends past | |
50 # the end of the node on which it resides. There are two cases: | |
51 # | |
52 # 1. The first term on the node. | |
53 # 2. The second or subsequent term on the node (prefix compressed term). | |
54 # | |
55 do_execsql_test 2.0 { | |
56 CREATE VIRTUAL TABLE t1 USING fts3; | |
57 BEGIN; | |
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 INSERT INTO t1 VALUES('hello'); | |
63 COMMIT; | |
64 } {} | |
65 do_test fts3corrupt-2.1 { | |
66 set blob [db one {SELECT root from t1_segdir}] | |
67 set blob [binary format a*a* "\x00\x7F" [string range $blob 2 end]] | |
68 execsql { UPDATE t1_segdir SET root = $blob } | |
69 } {} | |
70 do_catchsql_test 2.2 { | |
71 SELECT rowid FROM t1 WHERE t1 MATCH 'hello' | |
72 } {1 {database disk image is malformed}} | |
73 do_test 2.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
74 | |
75 do_execsql_test 3.0 { | |
76 DROP TABLE t1; | |
77 CREATE VIRTUAL TABLE t1 USING fts3; | |
78 BEGIN; | |
79 INSERT INTO t1 VALUES('hello'); | |
80 INSERT INTO t1 VALUES('world'); | |
81 COMMIT; | |
82 } {} | |
83 do_test fts3corrupt-3.1 { | |
84 set blob [db one {SELECT quote(root) from t1_segdir}] | |
85 set blob [binary format a11a*a* $blob "\x7F" [string range $blob 12 end]] | |
86 execsql { UPDATE t1_segdir SET root = $blob } | |
87 } {} | |
88 do_catchsql_test 3.2 { | |
89 SELECT rowid FROM t1 WHERE t1 MATCH 'world' | |
90 } {1 {database disk image is malformed}} | |
91 do_test 3.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
92 | |
93 | |
94 do_execsql_test 4.0 { | |
95 DROP TABLE t1; | |
96 CREATE VIRTUAL TABLE t1 USING fts3; | |
97 INSERT INTO t1(t1) VALUES('nodesize=24'); | |
98 } | |
99 do_test fts3corrupt-4.1 { | |
100 execsql BEGIN | |
101 foreach s { | |
102 "amxtvoo adqwroyhz auq aithtir avniqnuynvf axp ahibayfynig agbicpm" | |
103 "ajdtebs anteaxr aieynenwmd awpl alo akxcrwow aoxftge aoqvgul" | |
104 "amcfvdr auz apu aebelm ahuxyz aqc asyafdb agulvhvqu" | |
105 "apepwfyz azkhdvkw aenyelxzbk aslnitbyet aycdsdcpgr aqzzdbc agfi axnypydou" | |
106 "aaqrzzcm apcxdxo atumltzj aevvivo aodknoft aqoyytoz alobx apldt" | |
107 } { | |
108 execsql { INSERT INTO t1 VALUES($s) } | |
109 } | |
110 execsql COMMIT | |
111 } {} | |
112 | |
113 do_catchsql_test 4.2 { | |
114 UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF'; | |
115 SELECT rowid FROM t1 WHERE t1 MATCH 'world'; | |
116 } {1 {database disk image is malformed}} | |
117 do_test 4.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
118 | |
119 set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \ | |
120 22 120 [string repeat a 120] \ | |
121 22 120 [string repeat b 120] \ | |
122 22 120 [string repeat c 120] \ | |
123 22 120 [string repeat d 120] \ | |
124 22 120 [string repeat e 120] \ | |
125 22 120 [string repeat f 120] \ | |
126 22 120 [string repeat g 120] \ | |
127 22 120 [string repeat h 120] \ | |
128 22 120 [string repeat i 120] \ | |
129 22 120 [string repeat j 120] \ | |
130 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | |
131 ] | |
132 | |
133 do_catchsql_test 4.3 { | |
134 UPDATE t1_segdir SET root = $blob; | |
135 SELECT rowid FROM t1 WHERE t1 MATCH 'world'; | |
136 } {1 {database disk image is malformed}} | |
137 do_test 4.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
138 | |
139 # Test a special kind of corruption, where the %_stat table contains | |
140 # an invalid entry. At one point this could lead to a division-by-zero | |
141 # error in fts4. | |
142 # | |
143 do_execsql_test 5.0 { | |
144 DROP TABLE t1; | |
145 CREATE VIRTUAL TABLE t1 USING fts4; | |
146 } | |
147 do_test 5.1 { | |
148 db func nn nn | |
149 execsql BEGIN | |
150 execsql { INSERT INTO t1 VALUES('one') } | |
151 execsql { INSERT INTO t1 VALUES('two') } | |
152 execsql { INSERT INTO t1 VALUES('three') } | |
153 execsql { INSERT INTO t1 VALUES('four') } | |
154 execsql COMMIT | |
155 } {} | |
156 do_catchsql_test 5.2 { | |
157 UPDATE t1_stat SET value = X'0000'; | |
158 SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; | |
159 } {1 {database disk image is malformed}} | |
160 do_test 5.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
161 do_catchsql_test 5.3 { | |
162 UPDATE t1_stat SET value = NULL; | |
163 SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; | |
164 } {1 {database disk image is malformed}} | |
165 do_test 5.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB | |
166 | |
167 | |
168 finish_test | |
OLD | NEW |