| OLD | NEW |
| 1 # 2004 August 30 | 1 # 2004 August 30 |
| 2 # | 2 # |
| 3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
| 5 # | 5 # |
| 6 # May you do good and not evil. | 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
| 9 # | 9 # |
| 10 #*********************************************************************** | 10 #*********************************************************************** |
| 11 # This file implements regression tests for SQLite library. | 11 # This file implements regression tests for SQLite library. |
| 12 # | 12 # |
| 13 # This file implements tests to make sure SQLite does not crash or | 13 # This file implements tests to make sure SQLite does not crash or |
| 14 # segfault if it sees a corrupt database file. | 14 # segfault if it sees a corrupt database file. |
| 15 # | 15 # |
| 16 # $Id: corrupt2.test,v 1.20 2009/04/06 17:50:03 danielk1977 Exp $ | 16 # $Id: corrupt2.test,v 1.20 2009/04/06 17:50:03 danielk1977 Exp $ |
| 17 | 17 |
| 18 set testdir [file dirname $argv0] | 18 set testdir [file dirname $argv0] |
| 19 source $testdir/tester.tcl | 19 source $testdir/tester.tcl |
| 20 | 20 |
| 21 # Do not use a codec for tests in this file, as the database file is | 21 # Do not use a codec for tests in this file, as the database file is |
| 22 # manipulated directly using tcl scripts (using the [hexio_write] command). | 22 # manipulated directly using tcl scripts (using the [hexio_write] command). |
| 23 # | 23 # |
| 24 do_not_use_codec | 24 do_not_use_codec |
| 25 | 25 |
| 26 # These tests deal with corrupt database files |
| 27 # |
| 28 database_may_be_corrupt |
| 29 |
| 26 set presql "" | 30 set presql "" |
| 27 catch { set presql "$::G(perm:presql);" } | 31 catch { set presql "$::G(perm:presql);" } |
| 28 unset -nocomplain ::G(perm:presql) | 32 unset -nocomplain ::G(perm:presql) |
| 29 | 33 |
| 30 # The following tests - corrupt2-1.* - create some databases corrupted in | 34 # The following tests - corrupt2-1.* - create some databases corrupted in |
| 31 # specific ways and ensure that SQLite detects them as corrupt. | 35 # specific ways and ensure that SQLite detects them as corrupt. |
| 32 # | 36 # |
| 33 do_test corrupt2-1.1 { | 37 do_test corrupt2-1.1 { |
| 34 execsql { | 38 execsql { |
| 35 PRAGMA auto_vacuum=0; | 39 PRAGMA auto_vacuum=0; |
| 36 PRAGMA page_size=1024; | 40 PRAGMA page_size=1024; |
| 37 CREATE TABLE abc(a, b, c); | 41 CREATE TABLE abc(a, b, c); |
| 38 } | 42 } |
| 39 } {} | 43 } {} |
| 40 | 44 |
| 41 do_test corrupt2-1.2 { | 45 do_test corrupt2-1.2 { |
| 42 | 46 |
| 43 # Corrupt the 16 byte magic string at the start of the file | 47 # Corrupt the 16 byte magic string at the start of the file |
| 44 file delete -force corrupt.db | 48 forcedelete corrupt.db |
| 45 file delete -force corrupt.db-journal | 49 forcedelete corrupt.db-journal |
| 46 copy_file test.db corrupt.db | 50 forcecopy test.db corrupt.db |
| 47 set f [open corrupt.db RDWR] | 51 set f [open corrupt.db RDWR] |
| 48 seek $f 8 start | 52 seek $f 8 start |
| 49 puts $f blah | 53 puts $f blah |
| 50 close $f | 54 close $f |
| 51 | 55 |
| 52 sqlite3 db2 corrupt.db | 56 sqlite3 db2 corrupt.db |
| 53 catchsql " | 57 catchsql " |
| 54 $::presql | 58 $::presql |
| 55 SELECT * FROM sqlite_master; | 59 SELECT * FROM sqlite_master; |
| 56 " db2 | 60 " db2 |
| 57 } {1 {file is encrypted or is not a database}} | 61 } {1 {file is encrypted or is not a database}} |
| 58 | 62 |
| 59 do_test corrupt2-1.3 { | 63 do_test corrupt2-1.3 { |
| 60 db2 close | 64 db2 close |
| 61 | 65 |
| 62 # Corrupt the page-size (bytes 16 and 17 of page 1). | 66 # Corrupt the page-size (bytes 16 and 17 of page 1). |
| 63 file delete -force corrupt.db | 67 forcedelete corrupt.db |
| 64 file delete -force corrupt.db-journal | 68 forcedelete corrupt.db-journal |
| 65 copy_file test.db corrupt.db | 69 forcecopy test.db corrupt.db |
| 66 set f [open corrupt.db RDWR] | 70 set f [open corrupt.db RDWR] |
| 67 fconfigure $f -encoding binary | 71 fconfigure $f -encoding binary |
| 68 seek $f 16 start | 72 seek $f 16 start |
| 69 puts -nonewline $f "\x00\xFF" | 73 puts -nonewline $f "\x00\xFF" |
| 70 close $f | 74 close $f |
| 71 | 75 |
| 72 sqlite3 db2 corrupt.db | 76 sqlite3 db2 corrupt.db |
| 73 catchsql " | 77 catchsql " |
| 74 $::presql | 78 $::presql |
| 75 SELECT * FROM sqlite_master; | 79 SELECT * FROM sqlite_master; |
| 76 " db2 | 80 " db2 |
| 77 } {1 {file is encrypted or is not a database}} | 81 } {1 {file is encrypted or is not a database}} |
| 78 | 82 |
| 79 do_test corrupt2-1.4 { | 83 do_test corrupt2-1.4 { |
| 80 db2 close | 84 db2 close |
| 81 | 85 |
| 82 # Corrupt the free-block list on page 1. | 86 # Corrupt the free-block list on page 1. |
| 83 file delete -force corrupt.db | 87 forcedelete corrupt.db |
| 84 file delete -force corrupt.db-journal | 88 forcedelete corrupt.db-journal |
| 85 copy_file test.db corrupt.db | 89 forcecopy test.db corrupt.db |
| 86 set f [open corrupt.db RDWR] | 90 set f [open corrupt.db RDWR] |
| 87 fconfigure $f -encoding binary | 91 fconfigure $f -encoding binary |
| 88 seek $f 101 start | 92 seek $f 101 start |
| 89 puts -nonewline $f "\xFF\xFF" | 93 puts -nonewline $f "\xFF\xFF" |
| 90 close $f | 94 close $f |
| 91 | 95 |
| 92 sqlite3 db2 corrupt.db | 96 sqlite3 db2 corrupt.db |
| 93 catchsql " | 97 catchsql " |
| 94 $::presql | 98 $::presql |
| 95 SELECT * FROM sqlite_master; | 99 SELECT * FROM sqlite_master; |
| 96 " db2 | 100 " db2 |
| 97 } {1 {database disk image is malformed}} | 101 } {1 {database disk image is malformed}} |
| 98 | 102 |
| 99 do_test corrupt2-1.5 { | 103 do_test corrupt2-1.5 { |
| 100 db2 close | 104 db2 close |
| 101 | 105 |
| 102 # Corrupt the free-block list on page 1. | 106 # Corrupt the free-block list on page 1. |
| 103 file delete -force corrupt.db | 107 forcedelete corrupt.db |
| 104 file delete -force corrupt.db-journal | 108 forcedelete corrupt.db-journal |
| 105 copy_file test.db corrupt.db | 109 forcecopy test.db corrupt.db |
| 106 set f [open corrupt.db RDWR] | 110 set f [open corrupt.db RDWR] |
| 107 fconfigure $f -encoding binary | 111 fconfigure $f -encoding binary |
| 108 seek $f 101 start | 112 seek $f 101 start |
| 109 puts -nonewline $f "\x00\xC8" | 113 puts -nonewline $f "\x00\xC8" |
| 110 seek $f 200 start | 114 seek $f 200 start |
| 111 puts -nonewline $f "\x00\x00" | 115 puts -nonewline $f "\x00\x00" |
| 112 puts -nonewline $f "\x10\x00" | 116 puts -nonewline $f "\x10\x00" |
| 113 close $f | 117 close $f |
| 114 | 118 |
| 115 sqlite3 db2 corrupt.db | 119 sqlite3 db2 corrupt.db |
| 116 catchsql " | 120 catchsql " |
| 117 $::presql | 121 $::presql |
| 118 SELECT * FROM sqlite_master; | 122 SELECT * FROM sqlite_master; |
| 119 " db2 | 123 " db2 |
| 120 } {1 {database disk image is malformed}} | 124 } {1 {database disk image is malformed}} |
| 121 db2 close | 125 db2 close |
| 122 | 126 |
| 123 # Corrupt a database by having 2 indices of the same name: | 127 # Corrupt a database by having 2 indices of the same name: |
| 124 do_test corrupt2-2.1 { | 128 do_test corrupt2-2.1 { |
| 125 | 129 |
| 126 file delete -force corrupt.db | 130 forcedelete corrupt.db |
| 127 file delete -force corrupt.db-journal | 131 forcedelete corrupt.db-journal |
| 128 copy_file test.db corrupt.db | 132 forcecopy test.db corrupt.db |
| 129 | 133 |
| 130 sqlite3 db2 corrupt.db | 134 sqlite3 db2 corrupt.db |
| 131 execsql " | 135 execsql " |
| 132 $::presql | 136 $::presql |
| 133 CREATE INDEX a1 ON abc(a); | 137 CREATE INDEX a1 ON abc(a); |
| 134 CREATE INDEX a2 ON abc(b); | 138 CREATE INDEX a2 ON abc(b); |
| 135 PRAGMA writable_schema = 1; | 139 PRAGMA writable_schema = 1; |
| 136 UPDATE sqlite_master | 140 UPDATE sqlite_master |
| 137 SET name = 'a3', sql = 'CREATE INDEX a3' || substr(sql, 16, 10000) | 141 SET name = 'a3', sql = 'CREATE INDEX a3' || substr(sql, 16, 10000) |
| 138 WHERE type = 'index'; | 142 WHERE type = 'index'; |
| 139 PRAGMA writable_schema = 0; | 143 PRAGMA writable_schema = 0; |
| 140 " db2 | 144 " db2 |
| 141 | 145 |
| 142 db2 close | 146 db2 close |
| 143 sqlite3 db2 corrupt.db | 147 sqlite3 db2 corrupt.db |
| 144 catchsql " | 148 catchsql " |
| 145 $::presql | 149 $::presql |
| 146 SELECT * FROM sqlite_master; | 150 SELECT * FROM sqlite_master; |
| 147 " db2 | 151 " db2 |
| 148 } {1 {malformed database schema (a3) - index a3 already exists}} | 152 } {1 {malformed database schema (a3) - index a3 already exists}} |
| 149 | 153 |
| 150 db2 close | 154 db2 close |
| 151 | 155 |
| 152 do_test corrupt2-3.1 { | 156 do_test corrupt2-3.1 { |
| 153 file delete -force corrupt.db | 157 forcedelete corrupt.db |
| 154 file delete -force corrupt.db-journal | 158 forcedelete corrupt.db-journal |
| 155 sqlite3 db2 corrupt.db | 159 sqlite3 db2 corrupt.db |
| 156 | 160 |
| 157 execsql " | 161 execsql " |
| 158 $::presql | 162 $::presql |
| 159 PRAGMA auto_vacuum = 1; | 163 PRAGMA auto_vacuum = 1; |
| 160 PRAGMA page_size = 1024; | 164 PRAGMA page_size = 1024; |
| 161 CREATE TABLE t1(a, b, c); | 165 CREATE TABLE t1(a, b, c); |
| 162 CREATE TABLE t2(a, b, c); | 166 CREATE TABLE t2(a, b, c); |
| 163 INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100)); | 167 INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100)); |
| 164 INSERT INTO t2 SELECT * FROM t2; | 168 INSERT INTO t2 SELECT * FROM t2; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 193 do_test corrupt2-4.1 { | 197 do_test corrupt2-4.1 { |
| 194 catchsql { | 198 catchsql { |
| 195 SELECT * FROM t2; | 199 SELECT * FROM t2; |
| 196 } db2 | 200 } db2 |
| 197 } {1 {database disk image is malformed}} | 201 } {1 {database disk image is malformed}} |
| 198 | 202 |
| 199 db2 close | 203 db2 close |
| 200 | 204 |
| 201 unset -nocomplain result | 205 unset -nocomplain result |
| 202 do_test corrupt2-5.1 { | 206 do_test corrupt2-5.1 { |
| 203 file delete -force corrupt.db | 207 forcedelete corrupt.db |
| 204 file delete -force corrupt.db-journal | 208 forcedelete corrupt.db-journal |
| 205 sqlite3 db2 corrupt.db | 209 sqlite3 db2 corrupt.db |
| 206 | 210 |
| 207 execsql " | 211 execsql " |
| 208 $::presql | 212 $::presql |
| 209 PRAGMA auto_vacuum = 0; | 213 PRAGMA auto_vacuum = 0; |
| 210 PRAGMA page_size = 1024; | 214 PRAGMA page_size = 1024; |
| 211 CREATE TABLE t1(a, b, c); | 215 CREATE TABLE t1(a, b, c); |
| 212 CREATE TABLE t2(a, b, c); | 216 CREATE TABLE t2(a, b, c); |
| 213 INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100)); | 217 INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100)); |
| 214 INSERT INTO t2 SELECT * FROM t2; | 218 INSERT INTO t2 SELECT * FROM t2; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 254 |
| 251 db2 close | 255 db2 close |
| 252 | 256 |
| 253 proc corruption_test {args} { | 257 proc corruption_test {args} { |
| 254 set A(-corrupt) {} | 258 set A(-corrupt) {} |
| 255 set A(-sqlprep) {} | 259 set A(-sqlprep) {} |
| 256 set A(-tclprep) {} | 260 set A(-tclprep) {} |
| 257 array set A $args | 261 array set A $args |
| 258 | 262 |
| 259 catch {db close} | 263 catch {db close} |
| 260 file delete -force corrupt.db | 264 forcedelete corrupt.db |
| 261 file delete -force corrupt.db-journal | 265 forcedelete corrupt.db-journal |
| 262 | 266 |
| 263 sqlite3 db corrupt.db | 267 sqlite3 db corrupt.db |
| 264 db eval $::presql | 268 db eval $::presql |
| 265 eval $A(-tclprep) | 269 eval $A(-tclprep) |
| 266 db eval $A(-sqlprep) | 270 db eval $A(-sqlprep) |
| 267 db close | 271 db close |
| 268 | 272 |
| 269 eval $A(-corrupt) | 273 eval $A(-corrupt) |
| 270 | 274 |
| 271 sqlite3 db corrupt.db | 275 sqlite3 db corrupt.db |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 do_test corrupt2-13.2 { | 553 do_test corrupt2-13.2 { |
| 550 file size corrupt.db | 554 file size corrupt.db |
| 551 } [expr $::sqlite_pending_byte + 1024] | 555 } [expr $::sqlite_pending_byte + 1024] |
| 552 do_test corrupt2-13.3 { | 556 do_test corrupt2-13.3 { |
| 553 catchsql { DELETE FROM t1 WHERE rowid < 30; } | 557 catchsql { DELETE FROM t1 WHERE rowid < 30; } |
| 554 } {1 {database disk image is malformed}} | 558 } {1 {database disk image is malformed}} |
| 555 } | 559 } |
| 556 } | 560 } |
| 557 | 561 |
| 558 finish_test | 562 finish_test |
| OLD | NEW |