Index: third_party/sqlite/src/test/fts3corrupt.test |
diff --git a/third_party/sqlite/src/test/fts3corrupt.test b/third_party/sqlite/src/test/fts3corrupt.test |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b8b45c39518d03d9fd5f8721fd572118578701c3 |
--- /dev/null |
+++ b/third_party/sqlite/src/test/fts3corrupt.test |
@@ -0,0 +1,162 @@ |
+# 2010 October 27 |
+# |
+# May you do good and not evil. |
+# May you find forgiveness for yourself and forgive others. |
+# May you share freely, never taking more than you give. |
+# |
+#*********************************************************************** |
+# Test that the FTS3 extension does not crash when it encounters a |
+# corrupt data structure on disk. |
+# |
+ |
+ |
+set testdir [file dirname $argv0] |
+source $testdir/tester.tcl |
+ |
+# If SQLITE_ENABLE_FTS3 is not defined, omit this file. |
+ifcapable !fts3 { finish_test ; return } |
+ |
+set ::testprefix fts3corrupt |
+ |
+ |
+# Test that a doclist with a length field that indicates that the doclist |
+# extends past the end of the node on which it resides is correctly identified |
+# as database corruption. |
+# |
+do_execsql_test 1.0 { |
+ CREATE VIRTUAL TABLE t1 USING fts3; |
+ INSERT INTO t1 VALUES('hello'); |
+} {} |
+do_test fts3corrupt-1.1 { |
+ set blob [db one {SELECT root from t1_segdir}] |
+ set blob [binary format a7ca* $blob 24 [string range $blob 8 end]] |
+ execsql { UPDATE t1_segdir SET root = $blob } |
+} {} |
+do_test fts3corrupt-1.2 { |
+ foreach w {a b c d e f g h i j k l m n o} { |
+ execsql { INSERT INTO t1 VALUES($w) } |
+ } |
+} {} |
+do_catchsql_test 1.3 { |
+ INSERT INTO t1 VALUES('world'); |
+} {1 {database disk image is malformed}} |
+do_execsql_test 1.4 { |
+ DROP TABLE t1; |
+} |
+ |
+# This block of tests checks that corruption is correctly detected if the |
+# length field of a term on a leaf node indicates that the term extends past |
+# the end of the node on which it resides. There are two cases: |
+# |
+# 1. The first term on the node. |
+# 2. The second or subsequent term on the node (prefix compressed term). |
+# |
+do_execsql_test 2.0 { |
+ CREATE VIRTUAL TABLE t1 USING fts3; |
+ BEGIN; |
+ INSERT INTO t1 VALUES('hello'); |
+ INSERT INTO t1 VALUES('hello'); |
+ INSERT INTO t1 VALUES('hello'); |
+ INSERT INTO t1 VALUES('hello'); |
+ INSERT INTO t1 VALUES('hello'); |
+ COMMIT; |
+} {} |
+do_test fts3corrupt-2.1 { |
+ set blob [db one {SELECT root from t1_segdir}] |
+ set blob [binary format a*a* "\x00\x7F" [string range $blob 2 end]] |
+ execsql { UPDATE t1_segdir SET root = $blob } |
+} {} |
+do_catchsql_test 2.2 { |
+ SELECT rowid FROM t1 WHERE t1 MATCH 'hello' |
+} {1 {database disk image is malformed}} |
+ |
+do_execsql_test 3.0 { |
+ DROP TABLE t1; |
+ CREATE VIRTUAL TABLE t1 USING fts3; |
+ BEGIN; |
+ INSERT INTO t1 VALUES('hello'); |
+ INSERT INTO t1 VALUES('world'); |
+ COMMIT; |
+} {} |
+do_test fts3corrupt-3.1 { |
+ set blob [db one {SELECT quote(root) from t1_segdir}] |
+ set blob [binary format a11a*a* $blob "\x7F" [string range $blob 12 end]] |
+ execsql { UPDATE t1_segdir SET root = $blob } |
+} {} |
+do_catchsql_test 3.2 { |
+ SELECT rowid FROM t1 WHERE t1 MATCH 'world' |
+} {1 {database disk image is malformed}} |
+ |
+ |
+do_execsql_test 4.0 { |
+ DROP TABLE t1; |
+ CREATE VIRTUAL TABLE t1 USING fts3; |
+ INSERT INTO t1(t1) VALUES('nodesize=24'); |
+} |
+do_test fts3corrupt-4.1 { |
+ execsql BEGIN |
+ foreach s { |
+ "amxtvoo adqwroyhz auq aithtir avniqnuynvf axp ahibayfynig agbicpm" |
+ "ajdtebs anteaxr aieynenwmd awpl alo akxcrwow aoxftge aoqvgul" |
+ "amcfvdr auz apu aebelm ahuxyz aqc asyafdb agulvhvqu" |
+ "apepwfyz azkhdvkw aenyelxzbk aslnitbyet aycdsdcpgr aqzzdbc agfi axnypydou" |
+ "aaqrzzcm apcxdxo atumltzj aevvivo aodknoft aqoyytoz alobx apldt" |
+ } { |
+ execsql { INSERT INTO t1 VALUES($s) } |
+ } |
+ execsql COMMIT |
+} {} |
+ |
+do_catchsql_test 4.2 { |
+ UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF'; |
+ SELECT rowid FROM t1 WHERE t1 MATCH 'world'; |
+} {1 {database disk image is malformed}} |
+ |
+set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \ |
+ 22 120 [string repeat a 120] \ |
+ 22 120 [string repeat b 120] \ |
+ 22 120 [string repeat c 120] \ |
+ 22 120 [string repeat d 120] \ |
+ 22 120 [string repeat e 120] \ |
+ 22 120 [string repeat f 120] \ |
+ 22 120 [string repeat g 120] \ |
+ 22 120 [string repeat h 120] \ |
+ 22 120 [string repeat i 120] \ |
+ 22 120 [string repeat j 120] \ |
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
+] |
+ |
+do_catchsql_test 4.3 { |
+ UPDATE t1_segdir SET root = $blob; |
+ SELECT rowid FROM t1 WHERE t1 MATCH 'world'; |
+} {1 {database disk image is malformed}} |
+ |
+# Test a special kind of corruption, where the %_stat table contains |
+# an invalid entry. At one point this could lead to a division-by-zero |
+# error in fts4. |
+# |
+do_execsql_test 5.0 { |
+ DROP TABLE t1; |
+ CREATE VIRTUAL TABLE t1 USING fts4; |
+} |
+do_test 5.1 { |
+ db func nn nn |
+ execsql BEGIN |
+ execsql { INSERT INTO t1 VALUES('one') } |
+ execsql { INSERT INTO t1 VALUES('two') } |
+ execsql { INSERT INTO t1 VALUES('three') } |
+ execsql { INSERT INTO t1 VALUES('four') } |
+ execsql COMMIT |
+} {} |
+do_catchsql_test 5.2 { |
+ UPDATE t1_stat SET value = X'0000'; |
+ SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; |
+} {1 {database disk image is malformed}} |
+do_catchsql_test 5.3 { |
+ UPDATE t1_stat SET value = NULL; |
+ SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; |
+} {1 {database disk image is malformed}} |
+ |
+ |
+finish_test |
+ |