AryaWu/sqlite
0
1# 2014-01-202#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#12 13set testdir [file dirname $argv0]14source $testdir/tester.tcl15set testprefix corruptH16 17# This module uses hard-coded offsets which do not work if the reserved_bytes18# value is nonzero.19if {[nonzero_reserved_bytes]} {finish_test; return;}20 21database_may_be_corrupt22 23# The corruption migrations tested by the code in this file are not detected24# mmap mode.25#26# The reason is that in mmap mode, the different queries may use different27# PgHdr objects for the same page (same data, but different PgHdr container 28# objects). And so the corruption is not detected. 29#30if {[permutation]=="mmap"} {31 finish_test32 return33}34 35# Initialize the database.36#37do_execsql_test 1.1 {38 PRAGMA page_size=1024;39 40 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);41 INSERT INTO t1 VALUES(1, 'one');42 INSERT INTO t1 VALUES(2, 'two');43 44 CREATE TABLE t2(x);45 INSERT INTO t2 VALUES(randomblob(200));46 INSERT INTO t2 SELECT randomblob(200) FROM t2;47 INSERT INTO t2 SELECT randomblob(200) FROM t2;48 INSERT INTO t2 SELECT randomblob(200) FROM t2;49 INSERT INTO t2 SELECT randomblob(200) FROM t2;50 INSERT INTO t2 SELECT randomblob(200) FROM t2;51 INSERT INTO t2 SELECT randomblob(200) FROM t2;52} {}53 54# Corrupt the file so that the root page of t1 is also linked into t2 as55# a leaf page.56#57do_test 1.2 {58 db eval { SELECT name, rootpage FROM sqlite_master } { 59 set r($name) $rootpage 60 }61 db close62 hexio_write test.db [expr {($r(t2)-1)*1024 + 11}] [format %.2X $r(t1)]63 sqlite3 db test.db64} {}65 66do_test 1.3 {67 db eval { PRAGMA secure_delete=1 }68 list [catch {69 db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {70 db eval { DELETE FROM t2 }71 }72 } msg] $msg73} {1 {database disk image is malformed}}74 75#-------------------------------------------------------------------------76reset_db77 78# Initialize the database.79#80do_execsql_test 2.1 {81 PRAGMA auto_vacuum=0;82 PRAGMA page_size=1024;83 84 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);85 INSERT INTO t1 VALUES(1, 'one');86 INSERT INTO t1 VALUES(2, 'two');87 88 CREATE TABLE t3(x);89 90 CREATE TABLE t2(x PRIMARY KEY) WITHOUT ROWID;91 INSERT INTO t2 VALUES(randomblob(100));92 93 DROP TABLE t3;94} {}95 96do_test 2.2 {97 db eval { SELECT name, rootpage FROM sqlite_master } { 98 set r($name) $rootpage 99 }100 db close101 set fl [hexio_get_int [hexio_read test.db 32 4]]102 103 hexio_write test.db [expr {($fl-1) * 1024 + 0}] 00000000 104 hexio_write test.db [expr {($fl-1) * 1024 + 4}] 00000001 105 hexio_write test.db [expr {($fl-1) * 1024 + 8}] [format %.8X $r(t1)]106 hexio_write test.db 36 00000002107 108 sqlite3 db test.db109} {}110 111 112# The trick here is that the root page of the tree scanned by the outer 113# query is also currently on the free-list. So while the first seek on114# the table (for a==1) works, by the time the second is attempted The 115# "INSERT INTO t2..." statements have recycled the root page of t1 and116# used it as an index leaf. Normally, BtreeMovetoUnpacked() detects117# that the PgHdr object associated with said root page does not match118# the cursor (as it is now marked with PgHdr.intKey==0) and returns119# SQLITE_CORRUPT. 120#121set res23 {1 {database disk image is malformed}}122do_test 2.3 {123 list [catch {124 set res [list]125 db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {126 db eval { 127 INSERT INTO t2 SELECT randomblob(100) FROM t2;128 INSERT INTO t2 SELECT randomblob(100) FROM t2;129 INSERT INTO t2 SELECT randomblob(100) FROM t2;130 INSERT INTO t2 SELECT randomblob(100) FROM t2;131 INSERT INTO t2 SELECT randomblob(100) FROM t2;132 }133 lappend res $b134 }135 set res136 } msg] $msg137} $res23138 139#-------------------------------------------------------------------------140reset_db141 142# Initialize the database.143#144do_execsql_test 3.1 {145 PRAGMA page_size=1024;146 147 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);148 INSERT INTO t1 VALUES(1, 'one');149 INSERT INTO t1 VALUES(2, 'two');150 151 CREATE TABLE t2(c INTEGER PRAGMA KEY, d);152 INSERT INTO t2 VALUES(1, randomblob(1100));153} {}154 155do_test 3.2 {156 db eval { SELECT name, rootpage FROM sqlite_master } { 157 set r($name) $rootpage 158 }159 db close160 161 hexio_write test.db [expr {($r(t2)-1) * 1024 + 1020}] 00000002162 163 sqlite3 db test.db164} {}165 166do_test 3.3 {167 list [catch {168 db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {169 db eval { 170 DELETE FROM t2 WHERE c=1;171 }172 }173 } msg] $msg174} {1 {database disk image is malformed}}175 176finish_test177 