1# 2010 October 30
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
12set testdir [file dirname $argv0]
13source $testdir/tester.tcl
14
15# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
16ifcapable !fts3 { finish_test ; return }
17
18set ::testprefix fts3corrupt2
19
20set data [list]
21lappend data {*}{
22   "amxtvoo adqwroyhz auq aithtir avniqnuynvf axp ahibayfynig agbicpm"
23   "ajdtebs anteaxr aieynenwmd awpl alo akxcrwow aoxftge aoqvgul"
24   "amcfvdr auz apu aebelm ahuxyz aqc asyafdb agulvhvqu"
25   "apepwfyz azkhdvkw aenyelxzbk aslnitbyet aycdsdcpgr aqzzdbc agfi axnypydou"
26   "aaqrzzcm apcxdxo atumltzj aevvivo aodknoft aqoyytoz alobx apldt"
27   "adjllxlhnmj aiuhvuj adwppceuht atvj azrsam ahkjqdhny audlqxr aotgcd"
28   "aira azflsceos awj auzbobfkc awmezplr aeh awec ahndxlmv"
29   "aydwnied alk auoap agihyqeix aymqxzajnl aydwnied aojkarx agbo"
30   "ahajsmcl anvx amdhjm aoptsj agugzjjm apkevm acnj acjg"
31   "amwtkw aogttbykvt aubwrfqnbjf ajow agsj aerkqzjdqst anenlvbalkn arfajzzgckx"
32   "adqqqofkmz amjpavjuhw aqgehgnb awvvxlbtqzn agstqko akmkzehyh atagzey agwja"
33   "amag ahe autkllywhr avnk atmt akn anvdh aixfrv"
34   "aqdyerbws avefykly awl azaduojgzo anxfsmw axpt abgbvk ati"
35   "attyqkwz aiweypiczul afy asitaqbczhh aitxisizpv auhviq aibql ajfqc"
36   "aylzprtmta aiuemihqrpi awluvgsw ampbuy axlifpzfqr aems aoaxwads apianfn"
37   "aodrkijelq acdb aaserrdxm aqyasgofqu aevvivo afi apmwu aeoqysl"
38   "amqnk ankaotm ayfy ajcupeeoc advcbukan aucahlwnyk adbfyo azqjpeant"
39   "afczpp asqrs ahslvda akhlf aiqgdp atyd aznuglxqbrg awirndrh"
40   "aqhiajp amxeazb asxuehg akod axvolvsp agcz asmovmohy acmqa"
41   "avvomv aafms ashuaec arevx audtq alrwqhjvao avgsgpg ajbrctpsel"
42   "atxoirr ayopboobqdu ajunntua arh aernimxid aipljda aglo aefk"
43   "aonxf acmnnkna abgviaswe aulvcbv axp apemgakpzo aibql acioaid"
44   "axo alrwqhjvao ayqounftdzl azmoakdyh apajze ajk artvy apxiamy"
45   "ayjafsraz addjj agsj asejtziqws acatvhegu aoxdjqblsvv aekdmmbs aaobe"
46   "abjjvzubkwt alczv ati awz auyxgcxeb aymjoym anqoukprtyt atwfhpmbooh"
47   "ajfqz aethlgir aclcx aowlyvetby aproqm afjlqtkv anebfy akzrcpfrrvw"
48   "aoledfotm aiwlfm aeejlaej anz abgbvk aktfn aayoh anpywgdvgz"
49   "acvmldguld asdvz aqb aeomsyzyu aggylhprbdz asrfkwz auipybpsn agsnszzfb"
50}
51
52do_test fts3corrupt2-1.0 {
53  execsql BEGIN
54  execsql { CREATE VIRTUAL TABLE t2 USING FTS3(a, b); }
55  execsql { INSERT INTO t2(t2) VALUES('nodesize=32') }
56  foreach d $data {
57    execsql { INSERT INTO t2 VALUES($d, $d) }
58  }
59  execsql COMMIT
60  execsql { SELECT count(*) FROM t2_segments }
61} {163}
62
63proc set_byte {blob byte val} {
64  binary format a*ca*                         \
65      [string range $blob 0 [expr $byte-1]]   \
66      $val                                    \
67      [string range $blob [expr $byte+1] end] \
68}
69
70set tn 0
71set c 256
72foreach {rowid sz blob} [
73  db eval {SELECT rowid, length(block), block FROM t2_segments}
74] {
75  incr tn
76  set c [expr (($c+255)%256)]
77  for {set i 0} {$i < $sz} {incr i} {
78    set b2 [set_byte $blob $i $c]
79    execsql { UPDATE t2_segments SET block = $b2 WHERE rowid = $rowid }
80    do_test fts3corrupt2-1.$tn.$i {
81      catchsql { SELECT * FROM t2 WHERE t2 MATCH 'a*' }
82      set {} {}
83    } {}
84  }
85  execsql { UPDATE t2_segments SET block = $blob WHERE rowid = $rowid }
86}
87
88foreach c {50 100 150 200 250} {
89  foreach {rowid sz blob} [
90    db eval {SELECT rowid, length(root), root FROM t2_segdir}
91  ] {
92    incr tn
93    for {set i 0} {$i < $sz} {incr i} {
94      set b2 [set_byte $blob $i $c]
95      execsql { UPDATE t2_segdir SET root = $b2 WHERE rowid = $rowid }
96      do_test fts3corrupt2-2.$c.$tn.$i {
97        catchsql { SELECT * FROM t2 WHERE t2 MATCH 'a*' }
98        set {} {}
99      } {}
100    }
101    execsql { UPDATE t2_segdir SET root = $blob WHERE rowid = $rowid }
102  }
103}
104
105
106
107
108
109
110finish_test
111