1f3840b06Sdrh# 2008 June 11 2f3840b06Sdrh# 3f3840b06Sdrh# The author disclaims copyright to this source code. In place of 4f3840b06Sdrh# a legal notice, here is a blessing: 5f3840b06Sdrh# 6f3840b06Sdrh# May you do good and not evil. 7f3840b06Sdrh# May you find forgiveness for yourself and forgive others. 8f3840b06Sdrh# May you share freely, never taking more than you give. 9f3840b06Sdrh# 10f3840b06Sdrh#*********************************************************************** 11f3840b06Sdrh# This file implements regression tests for SQLite library. 12f3840b06Sdrh# 13f3840b06Sdrh# This file implements tests to make sure SQLite does not crash or 14f3840b06Sdrh# segfault if it sees a corrupt database file. It specifically focuses 15f3840b06Sdrh# on corrupt cell offsets in a btree page. 16f3840b06Sdrh# 178f00a826Sdanielk1977# $Id: corrupt7.test,v 1.8 2009/08/10 10:18:08 danielk1977 Exp $ 18f3840b06Sdrh 19f3840b06Sdrhset testdir [file dirname $argv0] 20f3840b06Sdrhsource $testdir/tester.tcl 21f3840b06Sdrh 22*af3906a7Sdrh# This module uses hard-coded offsets which do not work if the reserved_bytes 23*af3906a7Sdrh# value is nonzero. 24*af3906a7Sdrhif {[nonzero_reserved_bytes]} {finish_test; return;} 2568928b6cSdan 2609fe6143Sdrh# These tests deal with corrupt database files 2709fe6143Sdrh# 2809fe6143Sdrhdatabase_may_be_corrupt 2909fe6143Sdrh 30f3840b06Sdrh# We must have the page_size pragma for these tests to work. 31f3840b06Sdrh# 32f3840b06Sdrhifcapable !pager_pragmas { 33f3840b06Sdrh finish_test 34f3840b06Sdrh return 35f3840b06Sdrh} 36f3840b06Sdrh 37f3840b06Sdrh# Create a simple, small database. 38f3840b06Sdrh# 39f3840b06Sdrhdo_test corrupt7-1.1 { 40f3840b06Sdrh execsql { 41f3840b06Sdrh PRAGMA auto_vacuum=OFF; 42f3840b06Sdrh PRAGMA page_size=1024; 43f3840b06Sdrh CREATE TABLE t1(x); 44f3840b06Sdrh INSERT INTO t1(x) VALUES(1); 45f3840b06Sdrh INSERT INTO t1(x) VALUES(2); 46f3840b06Sdrh INSERT INTO t1(x) SELECT x+2 FROM t1; 47f3840b06Sdrh INSERT INTO t1(x) SELECT x+4 FROM t1; 48f3840b06Sdrh INSERT INTO t1(x) SELECT x+8 FROM t1; 49f3840b06Sdrh } 50f3840b06Sdrh file size test.db 51f3840b06Sdrh} [expr {1024*2}] 52f3840b06Sdrh 53f3840b06Sdrh# Verify that the file format is as we expect. The page size 54f3840b06Sdrh# should be 1024 bytes. 55f3840b06Sdrh# 56f3840b06Sdrhdo_test corrupt7-1.2 { 57f3840b06Sdrh hexio_get_int [hexio_read test.db 16 2] 58f3840b06Sdrh} 1024 ;# The page size is 1024 59f3840b06Sdrhdo_test corrupt7-1.3 { 60f3840b06Sdrh hexio_get_int [hexio_read test.db 20 1] 61f3840b06Sdrh} 0 ;# Unused bytes per page is 0 62f3840b06Sdrh 63f3840b06Sdrhintegrity_check corrupt7-1.4 64f3840b06Sdrh 65f3840b06Sdrh# Deliberately corrupt some of the cell offsets in the btree page 66f3840b06Sdrh# on page 2 of the database. 67f3840b06Sdrhdo_test corrupt7-2.1 { 68f3840b06Sdrh db close 69f3840b06Sdrh hexio_write test.db 1062 FF 70f3840b06Sdrh sqlite3 db test.db 71f3840b06Sdrh db eval {PRAGMA integrity_check(1)} 72f3840b06Sdrh} {{*** in database main *** 73cbc6b71fSdrhOn tree page 2 cell 15: Offset 65457 out of range 945..1020}} 74f3840b06Sdrhdo_test corrupt7-2.2 { 75f3840b06Sdrh db close 76f3840b06Sdrh hexio_write test.db 1062 04 77f3840b06Sdrh sqlite3 db test.db 78f3840b06Sdrh db eval {PRAGMA integrity_check(1)} 79f3840b06Sdrh} {{*** in database main *** 80cbc6b71fSdrhOn tree page 2 cell 15: Offset 1201 out of range 945..1020}} 81f3840b06Sdrh 82ec1fc80cSdrh# The code path that was causing the buffer overrun that this test 83ec1fc80cSdrh# case was checking for was removed. 84ec1fc80cSdrh# 85ec1fc80cSdrh#do_test corrupt7-3.1 { 86ec1fc80cSdrh# execsql { 87ec1fc80cSdrh# DROP TABLE t1; 88ec1fc80cSdrh# CREATE TABLE t1(a, b); 89ec1fc80cSdrh# INSERT INTO t1 VALUES(1, 'one'); 90ec1fc80cSdrh# INSERT INTO t1 VALUES(100, 'one hundred'); 91ec1fc80cSdrh# INSERT INTO t1 VALUES(100000, 'one hundred thousand'); 92ec1fc80cSdrh# CREATE INDEX i1 ON t1(b); 93ec1fc80cSdrh# } 94ec1fc80cSdrh# db close 95ec1fc80cSdrh# 96ec1fc80cSdrh# # Locate the 3rd cell in the index. 97ec1fc80cSdrh# set cell_offset [hexio_get_int [hexio_read test.db [expr 1024*2 + 12] 2]] 98ec1fc80cSdrh# incr cell_offset [expr 1024*2] 99ec1fc80cSdrh# incr cell_offset 1 100ec1fc80cSdrh# 101ec1fc80cSdrh# # This write corrupts the "header-size" field of the database record 102ec1fc80cSdrh# # stored in the index cell. At one point this was causing sqlite to 103ec1fc80cSdrh# # reference invalid memory. 104ec1fc80cSdrh# hexio_write test.db $cell_offset FFFF7F 105ec1fc80cSdrh# 106ec1fc80cSdrh# sqlite3 db test.db 107ec1fc80cSdrh# catchsql { 108ec1fc80cSdrh# SELECT b FROM t1 WHERE b > 'o' AND b < 'p'; 109ec1fc80cSdrh# } 110ec1fc80cSdrh#} {1 {database disk image is malformed}} 111161546c7Sdanielk1977 112f3840b06Sdrhfinish_test 113