19f580ad8Sdanielk1977# 2008 Sep 10 29f580ad8Sdanielk1977# 39f580ad8Sdanielk1977# The author disclaims copyright to this source code. In place of 49f580ad8Sdanielk1977# a legal notice, here is a blessing: 59f580ad8Sdanielk1977# 69f580ad8Sdanielk1977# May you do good and not evil. 79f580ad8Sdanielk1977# May you find forgiveness for yourself and forgive others. 89f580ad8Sdanielk1977# May you share freely, never taking more than you give. 99f580ad8Sdanielk1977# 109f580ad8Sdanielk1977#*********************************************************************** 119f580ad8Sdanielk1977# This file implements regression tests for SQLite library. 129f580ad8Sdanielk1977# 139f580ad8Sdanielk1977# This file implements tests to make sure SQLite does not crash or 149f580ad8Sdanielk1977# segfault if it sees a corrupt database file. It specifically focuses 159f580ad8Sdanielk1977# on loops in the B-Tree structure. A loop is formed in a B-Tree structure 169f580ad8Sdanielk1977# when there exists a page that is both an a descendent or ancestor of 179f580ad8Sdanielk1977# itself. 189f580ad8Sdanielk1977# 1967fd7a9aSdanielk1977# Also test that an SQLITE_CORRUPT error is returned if a B-Tree page 2067fd7a9aSdanielk1977# contains a (corrupt) reference to a page greater than the configured 2167fd7a9aSdanielk1977# maximum page number. 2267fd7a9aSdanielk1977# 2389bc4bc6Sdanielk1977# $Id: corruptB.test,v 1.4 2009/07/21 19:25:24 danielk1977 Exp $ 249f580ad8Sdanielk1977 259f580ad8Sdanielk1977set testdir [file dirname $argv0] 269f580ad8Sdanielk1977source $testdir/tester.tcl 279f580ad8Sdanielk1977 2868928b6cSdan# Do not use a codec for tests in this file, as the database file is 2968928b6cSdan# manipulated directly using tcl scripts (using the [hexio_write] command). 3068928b6cSdan# 3168928b6cSdando_not_use_codec 3268928b6cSdan 33*09fe6143Sdrh# These tests deal with corrupt database files 34*09fe6143Sdrh# 35*09fe6143Sdrhdatabase_may_be_corrupt 36*09fe6143Sdrh 379f580ad8Sdanielk1977 389f580ad8Sdanielk1977do_test corruptB-1.1 { 399f580ad8Sdanielk1977 execsql { 409f580ad8Sdanielk1977 PRAGMA auto_vacuum = 1; 419f580ad8Sdanielk1977 CREATE TABLE t1(x); 429f580ad8Sdanielk1977 INSERT INTO t1 VALUES(randomblob(200)); 439f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 449f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 459f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 469f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 479f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 489f580ad8Sdanielk1977 } 499f580ad8Sdanielk1977 expr {[file size test.db] > (1024*9)} 509f580ad8Sdanielk1977} {1} 519f580ad8Sdanielk1977integrity_check corruptB-1.2 529f580ad8Sdanielk1977 53fda06befSmistachkinforcecopy test.db bak.db 549f580ad8Sdanielk1977 559f580ad8Sdanielk1977# Set the right-child of a B-Tree rootpage to refer to the root-page itself. 569f580ad8Sdanielk1977# 579f580ad8Sdanielk1977do_test corruptB-1.3.1 { 589f580ad8Sdanielk1977 set ::root [execsql {SELECT rootpage FROM sqlite_master}] 599f580ad8Sdanielk1977 set ::offset [expr {($::root-1)*1024}] 609f580ad8Sdanielk1977 hexio_write test.db [expr $offset+8] [hexio_render_int32 $::root] 619f580ad8Sdanielk1977} {4} 629f580ad8Sdanielk1977do_test corruptB-1.3.2 { 639f580ad8Sdanielk1977 sqlite3 db test.db 649f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 659f580ad8Sdanielk1977} {1 {database disk image is malformed}} 669f580ad8Sdanielk1977 679f580ad8Sdanielk1977# Set the left-child of a cell in a B-Tree rootpage to refer to the 689f580ad8Sdanielk1977# root-page itself. 699f580ad8Sdanielk1977# 709f580ad8Sdanielk1977do_test corruptB-1.4.1 { 719f580ad8Sdanielk1977 db close 72fda06befSmistachkin forcecopy bak.db test.db 739f580ad8Sdanielk1977 set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]] 749f580ad8Sdanielk1977 hexio_write test.db [expr $offset+$cell_offset] [hexio_render_int32 $::root] 759f580ad8Sdanielk1977} {4} 769f580ad8Sdanielk1977do_test corruptB-1.4.2 { 779f580ad8Sdanielk1977 sqlite3 db test.db 789f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 799f580ad8Sdanielk1977} {1 {database disk image is malformed}} 809f580ad8Sdanielk1977 819f580ad8Sdanielk1977# Now grow the table B-Tree so that it is more than 2 levels high. 829f580ad8Sdanielk1977# 839f580ad8Sdanielk1977do_test corruptB-1.5.1 { 849f580ad8Sdanielk1977 db close 85fda06befSmistachkin forcecopy bak.db test.db 869f580ad8Sdanielk1977 sqlite3 db test.db 879f580ad8Sdanielk1977 execsql { 889f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 899f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 909f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 919f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 929f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 939f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 949f580ad8Sdanielk1977 INSERT INTO t1 SELECT randomblob(200) FROM t1; 959f580ad8Sdanielk1977 } 969f580ad8Sdanielk1977} {} 979f580ad8Sdanielk1977 98fda06befSmistachkinforcecopy test.db bak.db 999f580ad8Sdanielk1977 1009f580ad8Sdanielk1977# Set the right-child pointer of the right-child of the root page to point 1019f580ad8Sdanielk1977# back to the root page. 1029f580ad8Sdanielk1977# 1039f580ad8Sdanielk1977do_test corruptB-1.6.1 { 1049f580ad8Sdanielk1977 db close 1059f580ad8Sdanielk1977 set iRightChild [hexio_get_int [hexio_read test.db [expr $offset+8] 4]] 1069f580ad8Sdanielk1977 set c_offset [expr ($iRightChild-1)*1024] 1079f580ad8Sdanielk1977 hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root] 1089f580ad8Sdanielk1977} {4} 1099f580ad8Sdanielk1977do_test corruptB-1.6.2 { 1109f580ad8Sdanielk1977 sqlite3 db test.db 1119f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 1129f580ad8Sdanielk1977} {1 {database disk image is malformed}} 1139f580ad8Sdanielk1977 1149f580ad8Sdanielk1977# Set the left-child pointer of a cell of the right-child of the root page to 1159f580ad8Sdanielk1977# point back to the root page. 1169f580ad8Sdanielk1977# 1179f580ad8Sdanielk1977do_test corruptB-1.7.1 { 1189f580ad8Sdanielk1977 db close 119fda06befSmistachkin forcecopy bak.db test.db 1209f580ad8Sdanielk1977 set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]] 1219f580ad8Sdanielk1977 hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root] 1229f580ad8Sdanielk1977} {4} 1239f580ad8Sdanielk1977do_test corruptB-1.7.2 { 1249f580ad8Sdanielk1977 sqlite3 db test.db 1259f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 1269f580ad8Sdanielk1977} {1 {database disk image is malformed}} 1279f580ad8Sdanielk1977 1289f580ad8Sdanielk1977do_test corruptB-1.8.1 { 1299f580ad8Sdanielk1977 db close 1309f580ad8Sdanielk1977 set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]] 1319f580ad8Sdanielk1977 set iLeftChild [ 1329f580ad8Sdanielk1977 hexio_get_int [hexio_read test.db [expr $offset+$cell_offset] 4] 1339f580ad8Sdanielk1977 ] 1349f580ad8Sdanielk1977 set c_offset [expr ($iLeftChild-1)*1024] 1359f580ad8Sdanielk1977 hexio_write test.db [expr $c_offset+8] [hexio_render_int32 $::root] 1369f580ad8Sdanielk1977} {4} 1379f580ad8Sdanielk1977do_test corruptB-1.8.2 { 1389f580ad8Sdanielk1977 sqlite3 db test.db 1399f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 1409f580ad8Sdanielk1977} {1 {database disk image is malformed}} 1419f580ad8Sdanielk1977 1429f580ad8Sdanielk1977# Set the left-child pointer of a cell of the right-child of the root page to 1439f580ad8Sdanielk1977# point back to the root page. 1449f580ad8Sdanielk1977# 1459f580ad8Sdanielk1977do_test corruptB-1.9.1 { 1469f580ad8Sdanielk1977 db close 147fda06befSmistachkin forcecopy bak.db test.db 1489f580ad8Sdanielk1977 set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]] 1499f580ad8Sdanielk1977 hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root] 1509f580ad8Sdanielk1977} {4} 1519f580ad8Sdanielk1977do_test corruptB-1.9.2 { 1529f580ad8Sdanielk1977 sqlite3 db test.db 1539f580ad8Sdanielk1977 catchsql { SELECT * FROM t1 } 1549f580ad8Sdanielk1977} {1 {database disk image is malformed}} 1559f580ad8Sdanielk1977 15667fd7a9aSdanielk1977#--------------------------------------------------------------------------- 15767fd7a9aSdanielk1977 15867fd7a9aSdanielk1977do_test corruptB-2.1.1 { 15967fd7a9aSdanielk1977 db close 160fda06befSmistachkin forcecopy bak.db test.db 16167fd7a9aSdanielk1977 hexio_write test.db [expr $offset+8] [hexio_render_int32 0x6FFFFFFF] 16267fd7a9aSdanielk1977} {4} 16367fd7a9aSdanielk1977do_test corruptB-2.1.2 { 16467fd7a9aSdanielk1977 sqlite3 db test.db 16567fd7a9aSdanielk1977 catchsql { SELECT * FROM t1 } 1668d8626feSdrh} {1 {database disk image is malformed}} 16767fd7a9aSdanielk1977 16867fd7a9aSdanielk1977#--------------------------------------------------------------------------- 16967fd7a9aSdanielk1977 17067fd7a9aSdanielk1977# Corrupt the header-size field of a database record. 17167fd7a9aSdanielk1977# 17267fd7a9aSdanielk1977do_test corruptB-3.1.1 { 17367fd7a9aSdanielk1977 db close 174fda06befSmistachkin forcecopy bak.db test.db 17567fd7a9aSdanielk1977 sqlite3 db test.db 17667fd7a9aSdanielk1977 set v [string repeat abcdefghij 200] 17767fd7a9aSdanielk1977 execsql { 17867fd7a9aSdanielk1977 CREATE TABLE t2(a); 17967fd7a9aSdanielk1977 INSERT INTO t2 VALUES($v); 18067fd7a9aSdanielk1977 } 18167fd7a9aSdanielk1977 set t2_root [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't2'}] 18267fd7a9aSdanielk1977 set iPage [expr ($t2_root-1)*1024] 18367fd7a9aSdanielk1977 set iCellarray [expr $iPage + 8] 18467fd7a9aSdanielk1977 set iRecord [hexio_get_int [hexio_read test.db $iCellarray 2]] 18567fd7a9aSdanielk1977 db close 18667fd7a9aSdanielk1977 hexio_write test.db [expr $iPage+$iRecord+3] FF00 18767fd7a9aSdanielk1977} {2} 18867fd7a9aSdanielk1977do_test corruptB-3.1.2 { 18967fd7a9aSdanielk1977 sqlite3 db test.db 19067fd7a9aSdanielk1977 catchsql { SELECT * FROM t2 } 19167fd7a9aSdanielk1977} {1 {database disk image is malformed}} 19267fd7a9aSdanielk1977 1939f580ad8Sdanielk1977finish_test 194