AryaWu/sqlite
0
1# 2007 Sept 72#3# The author disclaims copyright to this source code. In place of4# 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 or14# segfault if it sees a corrupt database file.15#16 17set testdir [file dirname $argv0]18source $testdir/tester.tcl19set testprefix corrupt420 21# This module uses hard-coded offsets which do not work if the reserved_bytes22# value is nonzero.23if {[nonzero_reserved_bytes]} {finish_test; return;}24 25# These tests deal with corrupt database files26#27database_may_be_corrupt28 29# We must have the page_size pragma for these tests to work.30#31ifcapable !pager_pragmas {32 finish_test33 return34}35 36# Create a database with a freelist containing at least two pages.37#38do_test corrupt4-1.1 {39 set bigstring [string repeat 0123456789 200]40 execsql {41 PRAGMA auto_vacuum=OFF;42 PRAGMA page_size=1024;43 CREATE TABLE t1(x);44 INSERT INTO t1 VALUES($bigstring);45 CREATE TABLE t2(y);46 INSERT INTO t2 VALUES(1);47 DROP TABLE t1;48 }49 file size test.db50} [expr {1024*4}]51 52# Verify that there are two pages on the freelist.53#54do_test corrupt4-1.2 {55 execsql {PRAGMA freelist_count}56} {2}57 58# Get the page number for the trunk of the freelist.59#60set trunkpgno [hexio_get_int [hexio_read test.db 32 4]]61set baseaddr [expr {($trunkpgno-1)*1024}]62 63# Verify that the trunk of the freelist has exactly one64# leaf.65#66do_test corrupt4-1.3 {67 hexio_get_int [hexio_read test.db [expr {$::baseaddr+4}] 4]68} {1}69 70# Insert a negative number as the number of leaves on the trunk.71# Then try to add a new element to the freelist.72#73do_test corrupt4-1.4 {74 hexio_write test.db [expr {$::baseaddr+4}] [hexio_render_int32 -100000000]75 db close76 sqlite3 db test.db77 catchsql {78 DROP TABLE t279 }80} {1 {database disk image is malformed}}81 82#-------------------------------------------------------------------------83 84reset_db85do_execsql_test 2.0 {86 PRAGMA page_size = 512;87 CREATE TABLE t1(a, b, c);88}89 90# Create a database with a schema so large that the root of the 91# sqlite_schema table is the grandparent of its leaves.92#93set nView 100094do_test 2.1 {95 execsql BEGIN96 for {set ii 0} {$ii<$nView} {incr ii} {97 execsql " CREATE VIEW v$ii AS SELECT a, b, c FROM t1 "98 }99 execsql COMMIT100} {}101db close102 103proc get2byte {fd offset} {104 seek $fd $offset105 set bin [read $fd 2]106 binary scan $bin S val107 set val108}109proc get4byte {fd offset} {110 seek $fd $offset111 set bin [read $fd 4]112 binary scan $bin I val113 set val114}115proc put4byte {fd offset val} {116 seek $fd $offset117 set bin [binary format I $val]118 puts -nonewline $fd $bin119}120 121# Page 1 is now the grandparent of its leaves. Corrupt the database by setting 122# the second rightmost child page number of page 1 to 1.123#124set fd [open test.db r+]125fconfigure $fd -translation binary126set nChild [get2byte $fd 103]127set offChild [get2byte $fd [expr 100+12+($nChild-2)*2]]128set pgnoChild [get4byte $fd $offChild]129put4byte $fd $offChild 1130close $fd131 132if {![info exists ::G(perm:presql)]} {133 sqlite3 db test.db134 135 do_catchsql_test 2.2 {136 PRAGMA writable_schema = 1;137 SELECT * FROM sqlite_schema;138 } {1 {database disk image is malformed}}139 140 do_test 2.3 {141 list [catch {142 for {set ii $nView} {$ii<$nView*2} {incr ii} {143 execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"144 }145 } msg] $msg146 } {1 {database disk image is malformed}}147}148 149finish_test150 