OLD | NEW |
| (Empty) |
1 # 2008 Sep 10 | |
2 # | |
3 # The author disclaims copyright to this source code. In place of | |
4 # a legal notice, here is a blessing: | |
5 # | |
6 # May you do good and not evil. | |
7 # May you find forgiveness for yourself and forgive others. | |
8 # May you share freely, never taking more than you give. | |
9 # | |
10 #*********************************************************************** | |
11 # This file implements regression tests for SQLite library. | |
12 # | |
13 # This file implements tests to make sure SQLite does not crash or | |
14 # segfault if it sees a corrupt database file. It specifically focuses | |
15 # on loops in the B-Tree structure. A loop is formed in a B-Tree structure | |
16 # when there exists a page that is both an a descendent or ancestor of | |
17 # itself. | |
18 # | |
19 # Also test that an SQLITE_CORRUPT error is returned if a B-Tree page | |
20 # contains a (corrupt) reference to a page greater than the configured | |
21 # maximum page number. | |
22 # | |
23 # $Id: corruptB.test,v 1.4 2009/07/21 19:25:24 danielk1977 Exp $ | |
24 | |
25 set testdir [file dirname $argv0] | |
26 source $testdir/tester.tcl | |
27 | |
28 # Do not use a codec for tests in this file, as the database file is | |
29 # manipulated directly using tcl scripts (using the [hexio_write] command). | |
30 # | |
31 do_not_use_codec | |
32 | |
33 # These tests deal with corrupt database files | |
34 # | |
35 database_may_be_corrupt | |
36 | |
37 | |
38 do_test corruptB-1.1 { | |
39 execsql { | |
40 PRAGMA auto_vacuum = 1; | |
41 CREATE TABLE t1(x); | |
42 INSERT INTO t1 VALUES(randomblob(200)); | |
43 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
44 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
45 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
46 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
47 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
48 } | |
49 expr {[file size test.db] > (1024*9)} | |
50 } {1} | |
51 integrity_check corruptB-1.2 | |
52 | |
53 forcecopy test.db bak.db | |
54 | |
55 # Set the right-child of a B-Tree rootpage to refer to the root-page itself. | |
56 # | |
57 do_test corruptB-1.3.1 { | |
58 set ::root [execsql {SELECT rootpage FROM sqlite_master}] | |
59 set ::offset [expr {($::root-1)*1024}] | |
60 hexio_write test.db [expr $offset+8] [hexio_render_int32 $::root] | |
61 } {4} | |
62 do_test corruptB-1.3.2 { | |
63 sqlite3 db test.db | |
64 catchsql { SELECT * FROM t1 } | |
65 } {1 {database disk image is malformed}} | |
66 | |
67 # Set the left-child of a cell in a B-Tree rootpage to refer to the | |
68 # root-page itself. | |
69 # | |
70 do_test corruptB-1.4.1 { | |
71 db close | |
72 forcecopy bak.db test.db | |
73 set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]] | |
74 hexio_write test.db [expr $offset+$cell_offset] [hexio_render_int32 $::root] | |
75 } {4} | |
76 do_test corruptB-1.4.2 { | |
77 sqlite3 db test.db | |
78 catchsql { SELECT * FROM t1 } | |
79 } {1 {database disk image is malformed}} | |
80 | |
81 # Now grow the table B-Tree so that it is more than 2 levels high. | |
82 # | |
83 do_test corruptB-1.5.1 { | |
84 db close | |
85 forcecopy bak.db test.db | |
86 sqlite3 db test.db | |
87 execsql { | |
88 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
89 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
90 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
91 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
92 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
93 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
94 INSERT INTO t1 SELECT randomblob(200) FROM t1; | |
95 } | |
96 } {} | |
97 | |
98 forcecopy test.db bak.db | |
99 | |
100 # Set the right-child pointer of the right-child of the root page to point | |
101 # back to the root page. | |
102 # | |
103 do_test corruptB-1.6.1 { | |
104 db close | |
105 set iRightChild [hexio_get_int [hexio_read test.db [expr $offset+8] 4]] | |
106 set c_offset [expr ($iRightChild-1)*1024] | |
107 hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root] | |
108 } {4} | |
109 do_test corruptB-1.6.2 { | |
110 sqlite3 db test.db | |
111 catchsql { SELECT * FROM t1 } | |
112 } {1 {database disk image is malformed}} | |
113 | |
114 # Set the left-child pointer of a cell of the right-child of the root page to | |
115 # point back to the root page. | |
116 # | |
117 do_test corruptB-1.7.1 { | |
118 db close | |
119 forcecopy bak.db test.db | |
120 set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]] | |
121 hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root] | |
122 } {4} | |
123 do_test corruptB-1.7.2 { | |
124 sqlite3 db test.db | |
125 catchsql { SELECT * FROM t1 } | |
126 } {1 {database disk image is malformed}} | |
127 | |
128 do_test corruptB-1.8.1 { | |
129 db close | |
130 set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]] | |
131 set iLeftChild [ | |
132 hexio_get_int [hexio_read test.db [expr $offset+$cell_offset] 4] | |
133 ] | |
134 set c_offset [expr ($iLeftChild-1)*1024] | |
135 hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root] | |
136 } {4} | |
137 do_test corruptB-1.8.2 { | |
138 sqlite3 db test.db | |
139 catchsql { SELECT * FROM t1 } | |
140 } {1 {database disk image is malformed}} | |
141 | |
142 # Set the left-child pointer of a cell of the right-child of the root page to | |
143 # point back to the root page. | |
144 # | |
145 do_test corruptB-1.9.1 { | |
146 db close | |
147 forcecopy bak.db test.db | |
148 set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]] | |
149 hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root] | |
150 } {4} | |
151 do_test corruptB-1.9.2 { | |
152 sqlite3 db test.db | |
153 catchsql { SELECT * FROM t1 } | |
154 } {1 {database disk image is malformed}} | |
155 | |
156 #--------------------------------------------------------------------------- | |
157 | |
158 do_test corruptB-2.1.1 { | |
159 db close | |
160 forcecopy bak.db test.db | |
161 hexio_write test.db [expr $offset+8] [hexio_render_int32 0x6FFFFFFF] | |
162 } {4} | |
163 do_test corruptB-2.1.2 { | |
164 sqlite3 db test.db | |
165 catchsql { SELECT * FROM t1 } | |
166 } {1 {database disk image is malformed}} | |
167 | |
168 #--------------------------------------------------------------------------- | |
169 | |
170 # Corrupt the header-size field of a database record. | |
171 # | |
172 do_test corruptB-3.1.1 { | |
173 db close | |
174 forcecopy bak.db test.db | |
175 sqlite3 db test.db | |
176 set v [string repeat abcdefghij 200] | |
177 execsql { | |
178 CREATE TABLE t2(a); | |
179 INSERT INTO t2 VALUES($v); | |
180 } | |
181 set t2_root [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't2'}] | |
182 set iPage [expr ($t2_root-1)*1024] | |
183 set iCellarray [expr $iPage + 8] | |
184 set iRecord [hexio_get_int [hexio_read test.db $iCellarray 2]] | |
185 db close | |
186 hexio_write test.db [expr $iPage+$iRecord+3] FF00 | |
187 } {2} | |
188 do_test corruptB-3.1.2 { | |
189 sqlite3 db test.db | |
190 catchsql { SELECT * FROM t2 } | |
191 } {1 {database disk image is malformed}} | |
192 | |
193 finish_test | |
OLD | NEW |