File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / corrupt9.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 4 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    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.1.1.1 2012/02/21 17:04:16 misho 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>