1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
# 2007 Sept 7
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corrupt4
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
database_may_be_corrupt
# We must have the page_size pragma for these tests to work.
#
ifcapable !pager_pragmas {
finish_test
return
}
# Create a database with a freelist containing at least two pages.
#
do_test corrupt4-1.1 {
set bigstring [string repeat 0123456789 200]
execsql {
PRAGMA auto_vacuum=OFF;
PRAGMA page_size=1024;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES($bigstring);
CREATE TABLE t2(y);
INSERT INTO t2 VALUES(1);
DROP TABLE t1;
}
file size test.db
} [expr {1024*4}]
# Verify that there are two pages on the freelist.
#
do_test corrupt4-1.2 {
execsql {PRAGMA freelist_count}
} {2}
# Get the page number for the trunk of the freelist.
#
set trunkpgno [hexio_get_int [hexio_read test.db 32 4]]
set baseaddr [expr {($trunkpgno-1)*1024}]
# Verify that the trunk of the freelist has exactly one
# leaf.
#
do_test corrupt4-1.3 {
hexio_get_int [hexio_read test.db [expr {$::baseaddr+4}] 4]
} {1}
# Insert a negative number as the number of leaves on the trunk.
# Then try to add a new element to the freelist.
#
do_test corrupt4-1.4 {
hexio_write test.db [expr {$::baseaddr+4}] [hexio_render_int32 -100000000]
db close
sqlite3 db test.db
catchsql {
DROP TABLE t2
}
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
PRAGMA page_size = 512;
CREATE TABLE t1(a, b, c);
}
# Create a database with a schema so large that the root of the
# sqlite_schema table is the grandparent of its leaves.
#
set nView 1000
do_test 2.1 {
execsql BEGIN
for {set ii 0} {$ii<$nView} {incr ii} {
execsql " CREATE VIEW v$ii AS SELECT a, b, c FROM t1 "
}
execsql COMMIT
} {}
db close
proc get2byte {fd offset} {
seek $fd $offset
set bin [read $fd 2]
binary scan $bin S val
set val
}
proc get4byte {fd offset} {
seek $fd $offset
set bin [read $fd 4]
binary scan $bin I val
set val
}
proc put4byte {fd offset val} {
seek $fd $offset
set bin [binary format I $val]
puts -nonewline $fd $bin
}
# Page 1 is now the grandparent of its leaves. Corrupt the database by setting
# the second rightmost child page number of page 1 to 1.
#
set fd [open test.db r+]
fconfigure $fd -encoding binary -translation binary
set nChild [get2byte $fd 103]
set offChild [get2byte $fd [expr 100+12+($nChild-2)*2]]
set pgnoChild [get4byte $fd $offChild]
put4byte $fd $offChild 1
close $fd
if {![info exists ::G(perm:presql)]} {
sqlite3 db test.db
do_catchsql_test 2.2 {
PRAGMA writable_schema = 1;
SELECT * FROM sqlite_schema;
} {1 {database disk image is malformed}}
do_test 2.3 {
list [catch {
for {set ii $nView} {$ii<$nView*2} {incr ii} {
execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"
}
} msg] $msg
} {1 {database disk image is malformed}}
}
finish_test
|