Annotation of embedaddon/sqlite3/test/corruptD.test, revision 1.1
1.1 ! misho 1: # 2009 June 3
! 2: #
! 3: # The author disclaims copyright to this source code. In place of
! 4: # 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: # $Id: corruptD.test,v 1.2 2009/06/05 17:09:12 drh Exp $
! 13:
! 14: set testdir [file dirname $argv0]
! 15: source $testdir/tester.tcl
! 16:
! 17: # Do not use a codec for tests in this file, as the database file is
! 18: # manipulated directly using tcl scripts (using the [hexio_write] command).
! 19: #
! 20: do_not_use_codec
! 21:
! 22: #--------------------------------------------------------------------------
! 23: # OVERVIEW
! 24: #
! 25: # This test file attempts to verify that SQLite does not read past the
! 26: # end of any in-memory buffers as a result of corrupted database page
! 27: # images. Usually this happens because a field within a database page
! 28: # that contains an offset to some other structure within the same page
! 29: # is set to too large a value. A database page contains the following
! 30: # such fields:
! 31: #
! 32: # 1. The page header field that contains the offset to the first
! 33: # free block of space.
! 34: #
! 35: # 2. The first two bytes of all but the last free block on the free-block
! 36: # list (the offset to the next free block).
! 37: #
! 38: # 3. The page header field containing the number of cells on the page
! 39: # (implicitly defines the offset to the final element in the cell offset
! 40: # array, which could potentially be off the end of the page).
! 41: #
! 42: # 4. The page header field containing the offset to the start of the cell
! 43: # content area.
! 44: #
! 45: # 5. The contents of the cell offset array.
! 46: #
! 47: # 6. The first few bytes of each cell determine the size of the cell
! 48: # stored within the page, and hence the offset to the final byte of
! 49: # the cell.
! 50: #
! 51: # If any of the above fields are set to too large a value, then a buffer
! 52: # overread may occur. This test script creates and operates on various
! 53: # strategically corrupted database files to attempt to provoke such buffer
! 54: # overreads.
! 55: #
! 56: # Very often, a buffer overread passes unnoticed, particularly in workstation
! 57: # environments. For this reason, this test script should be run using valgrind
! 58: # (or similar) in order to verify that no overreads occur.
! 59: #
! 60: # TEST PLAN
! 61: #
! 62: # Test cases corruptD-1.* are white-box tests. They attempt to corrupt
! 63: # one of the above fields, then exercise each part of the code in btree.c
! 64: # that uses said field.
! 65: #
! 66: # Offset variables 1, 2, 3 and 4 are all checked to make sure they
! 67: # will not result in buffer overruns as part of page initialization in
! 68: # sqlite3BtreeInitPage(). Offsets 5 and 6 cannot be tested as part of
! 69: # page initialization, as trying to do so causes a performance hit.
! 70: #
! 71:
! 72: do_test corruptD-1.0 {
! 73: execsql {
! 74: PRAGMA auto_vacuum = 0;
! 75: PRAGMA page_size = 1024;
! 76: CREATE TABLE t1(a, b);
! 77: CREATE INDEX i1 ON t1(a, b);
! 78: }
! 79: for {set ii 1} {$ii < 50} {incr ii} {
! 80: execsql { INSERT INTO t1 VALUES($ii, $ii * $ii) }
! 81: }
! 82: execsql {
! 83: DELETE FROM t1 WHERE a = 10;
! 84: DELETE FROM t1 WHERE a = 20;
! 85: DELETE FROM t1 WHERE a = 30;
! 86: DELETE FROM t1 WHERE a = 40;
! 87: }
! 88: forcecopy test.db test.bu
! 89: } {}
! 90:
! 91: proc incr_change_counter {} {
! 92: hexio_write test.db 24 [
! 93: hexio_render_int32 [expr [hexio_get_int [hexio_read test.db 24 4]] + 1]
! 94: ]
! 95: }
! 96:
! 97: proc restore_file {} {
! 98: db close
! 99: forcecopy test.bu test.db
! 100: sqlite3 db test.db
! 101: }
! 102:
! 103: #-------------------------------------------------------------------------
! 104: # The following tests, corruptD-1.1.*, focus on the page header field
! 105: # containing the offset of the first free block in a page.
! 106: #
! 107: do_test corruptD-1.1.1 {
! 108: incr_change_counter
! 109: hexio_write test.db [expr 1024+1] FFFF
! 110: catchsql { SELECT * FROM t1 }
! 111: } {1 {database disk image is malformed}}
! 112: do_test corruptD-1.1.2 {
! 113: incr_change_counter
! 114: hexio_write test.db [expr 1024+1] [hexio_render_int32 1021]
! 115: catchsql { SELECT * FROM t1 }
! 116: } {1 {database disk image is malformed}}
! 117:
! 118: #-------------------------------------------------------------------------
! 119: # The following tests, corruptD-1.2.*, focus on the offsets contained
! 120: # in the first 2 byte of each free-block on the free-list.
! 121: #
! 122: do_test corruptD-1.2.1 {
! 123: restore_file
! 124: } {}
! 125: do_test corruptD-1.2.2 {
! 126: } {}
! 127:
! 128: #-------------------------------------------------------------------------
! 129: # The following tests, corruptD-1.4.*, ...
! 130: #
! 131:
! 132:
! 133: #-------------------------------------------------------------------------
! 134: # The following tests, corruptD-1.5.*, focus on the offsets contained
! 135: # in the cell offset array.
! 136: #
! 137: # defragmentPage
! 138: #
! 139:
! 140: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>