Annotation of embedaddon/sqlite3/test/corrupt9.test, revision 1.1

1.1     ! misho       1: # 2008 July 9
        !             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: # This file implements regression tests for SQLite library.
        !            12: #
        !            13: # This file implements tests to make sure SQLite does not crash or
        !            14: # segfault if it sees a corrupt database file.  It specifically focuses
        !            15: # on corruption in the form of duplicate entries on the freelist.
        !            16: #
        !            17: # $Id: corrupt9.test,v 1.3 2009/06/04 02:47:04 shane Exp $
        !            18: 
        !            19: set testdir [file dirname $argv0]
        !            20: source $testdir/tester.tcl
        !            21: 
        !            22: # Do not use a codec for tests in this file, as the database file is
        !            23: # manipulated directly using tcl scripts (using the [hexio_write] command).
        !            24: #
        !            25: do_not_use_codec
        !            26: 
        !            27: # We must have the page_size pragma for these tests to work.
        !            28: #
        !            29: ifcapable !pager_pragmas {
        !            30:   finish_test
        !            31:   return
        !            32: }
        !            33: 
        !            34: # Return the offset to the first (trunk) page of the freelist.  Return
        !            35: # zero of the freelist is empty.
        !            36: #
        !            37: proc freelist_trunk_offset {filename} {
        !            38:   if {[hexio_read $filename 36 4]==0} {return 0}
        !            39:   set pgno [hexio_get_int [hexio_read $filename 32 4]]
        !            40:   return [expr {($pgno-1)*[hexio_get_int [hexio_read $filename 16 2]]}]
        !            41: }
        !            42: 
        !            43: # This procedure looks at the first trunk page of the freelist and
        !            44: # corrupts that page by overwriting up to N entries with duplicates
        !            45: # of the first entry.
        !            46: #
        !            47: proc corrupt_freelist {filename N} {
        !            48:   set offset [freelist_trunk_offset $filename]
        !            49:   if {$offset==0} {error "Freelist is empty"}
        !            50:   set cnt [hexio_get_int [hexio_read $filename [expr {$offset+4}] 4]]
        !            51:   set pgno [hexio_read $filename [expr {$offset+8}] 4]
        !            52:   for {set i 12} {$N>0 && $i<8+4*$cnt} {incr i 4; incr N -1} {
        !            53:     hexio_write $filename [expr {$offset+$i}] $pgno
        !            54:   }
        !            55: }
        !            56: 
        !            57: # Create a database to work with.  Make sure there are plenty of
        !            58: # entries on the freelist.
        !            59: #
        !            60: do_test corrupt9-1.1 {
        !            61:   execsql {
        !            62:     PRAGMA auto_vacuum=NONE;
        !            63:     PRAGMA page_size=1024;
        !            64:     CREATE TABLE t1(x);
        !            65:     INSERT INTO t1(x) VALUES(1);
        !            66:     INSERT INTO t1(x) VALUES(2);
        !            67:     INSERT INTO t1(x) SELECT x+2 FROM t1;
        !            68:     INSERT INTO t1(x) SELECT x+4 FROM t1;
        !            69:     INSERT INTO t1(x) SELECT x+8 FROM t1;
        !            70:     INSERT INTO t1(x) SELECT x+16 FROM t1;
        !            71:     INSERT INTO t1(x) SELECT x+32 FROM t1;
        !            72:     INSERT INTO t1(x) SELECT x+64 FROM t1;
        !            73:     INSERT INTO t1(x) SELECT x+128 FROM t1;
        !            74:     INSERT INTO t1(x) SELECT x+256 FROM t1;
        !            75:     CREATE TABLE t2(a,b);
        !            76:     INSERT INTO t2 SELECT x, x*x FROM t1;
        !            77:     CREATE INDEX i1 ON t1(x);
        !            78:     CREATE INDEX i2 ON t2(b,a);
        !            79:     DROP INDEX i2;
        !            80:   }
        !            81:   expr {[file size test.db]>1024*24}
        !            82: } {1}
        !            83: integrity_check corrupt9-1.2
        !            84: 
        !            85: # Corrupt the freelist by adding duplicate entries to the freelist.
        !            86: # Make sure the corruption is detected.
        !            87: #
        !            88: db close
        !            89: forcecopy test.db test.db-template
        !            90: 
        !            91: corrupt_freelist test.db 1
        !            92: sqlite3 db test.db
        !            93: do_test corrupt9-2.1 {
        !            94:   set x [db eval {PRAGMA integrity_check}]
        !            95:   expr {$x!="ok"}
        !            96: } {1}
        !            97: do_test corrupt9-2.2 {
        !            98:   catchsql {
        !            99:     CREATE INDEX i2 ON t2(b,a);
        !           100:     REINDEX;
        !           101:   }
        !           102: } {1 {database disk image is malformed}}
        !           103: 
        !           104: 
        !           105: db close
        !           106: forcecopy test.db-template test.db
        !           107: corrupt_freelist test.db 2
        !           108: sqlite3 db test.db
        !           109: do_test corrupt9-3.1 {
        !           110:   set x [db eval {PRAGMA integrity_check}]
        !           111:   expr {$x!="ok"}
        !           112: } {1}
        !           113: do_test corrupt9-3.2 {
        !           114:   catchsql {
        !           115:     CREATE INDEX i2 ON t2(b,a);
        !           116:     REINDEX;
        !           117:   }
        !           118: } {1 {database disk image is malformed}}
        !           119: 
        !           120: db close
        !           121: forcecopy test.db-template test.db
        !           122: corrupt_freelist test.db 3
        !           123: sqlite3 db test.db
        !           124: do_test corrupt9-4.1 {
        !           125:   set x [db eval {PRAGMA integrity_check}]
        !           126:   expr {$x!="ok"}
        !           127: } {1}
        !           128: do_test corrupt9-4.2 {
        !           129:   catchsql {
        !           130:     CREATE INDEX i2 ON t2(b,a);
        !           131:     REINDEX;
        !           132:   }
        !           133: } {1 {database disk image is malformed}}
        !           134:  
        !           135: 
        !           136: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>