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

1.1     ! misho       1: # 2004 August 30
        !             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.
        !            15: #
        !            16: # $Id: corrupt2.test,v 1.20 2009/04/06 17:50:03 danielk1977 Exp $
        !            17: 
        !            18: set testdir [file dirname $argv0]
        !            19: source $testdir/tester.tcl
        !            20: 
        !            21: # Do not use a codec for tests in this file, as the database file is
        !            22: # manipulated directly using tcl scripts (using the [hexio_write] command).
        !            23: #
        !            24: do_not_use_codec
        !            25: 
        !            26: set presql ""
        !            27: catch { set presql "$::G(perm:presql);" }
        !            28: unset -nocomplain ::G(perm:presql)
        !            29: 
        !            30: # The following tests - corrupt2-1.* - create some databases corrupted in
        !            31: # specific ways and ensure that SQLite detects them as corrupt.
        !            32: #
        !            33: do_test corrupt2-1.1 {
        !            34:   execsql {
        !            35:     PRAGMA auto_vacuum=0;
        !            36:     PRAGMA page_size=1024;
        !            37:     CREATE TABLE abc(a, b, c);
        !            38:   }
        !            39: } {}
        !            40: 
        !            41: do_test corrupt2-1.2 {
        !            42: 
        !            43:   # Corrupt the 16 byte magic string at the start of the file
        !            44:   forcedelete corrupt.db
        !            45:   forcedelete corrupt.db-journal
        !            46:   forcecopy test.db corrupt.db
        !            47:   set f [open corrupt.db RDWR]
        !            48:   seek $f 8 start
        !            49:   puts $f blah
        !            50:   close $f
        !            51: 
        !            52:   sqlite3 db2 corrupt.db
        !            53:   catchsql "
        !            54:     $::presql
        !            55:     SELECT * FROM sqlite_master;
        !            56:   " db2
        !            57: } {1 {file is encrypted or is not a database}}
        !            58: 
        !            59: do_test corrupt2-1.3 {
        !            60:   db2 close
        !            61: 
        !            62:   # Corrupt the page-size (bytes 16 and 17 of page 1).
        !            63:   forcedelete corrupt.db
        !            64:   forcedelete corrupt.db-journal
        !            65:   forcecopy test.db corrupt.db
        !            66:   set f [open corrupt.db RDWR]
        !            67:   fconfigure $f -encoding binary
        !            68:   seek $f 16 start
        !            69:   puts -nonewline $f "\x00\xFF"
        !            70:   close $f
        !            71: 
        !            72:   sqlite3 db2 corrupt.db
        !            73:   catchsql "
        !            74:     $::presql
        !            75:     SELECT * FROM sqlite_master;
        !            76:   " db2
        !            77: } {1 {file is encrypted or is not a database}}
        !            78: 
        !            79: do_test corrupt2-1.4 {
        !            80:   db2 close
        !            81: 
        !            82:   # Corrupt the free-block list on page 1.
        !            83:   forcedelete corrupt.db
        !            84:   forcedelete corrupt.db-journal
        !            85:   forcecopy test.db corrupt.db
        !            86:   set f [open corrupt.db RDWR]
        !            87:   fconfigure $f -encoding binary
        !            88:   seek $f 101 start
        !            89:   puts -nonewline $f "\xFF\xFF"
        !            90:   close $f
        !            91: 
        !            92:   sqlite3 db2 corrupt.db
        !            93:   catchsql "
        !            94:     $::presql
        !            95:     SELECT * FROM sqlite_master;
        !            96:   " db2
        !            97: } {1 {database disk image is malformed}}
        !            98: 
        !            99: do_test corrupt2-1.5 {
        !           100:   db2 close
        !           101: 
        !           102:   # Corrupt the free-block list on page 1.
        !           103:   forcedelete corrupt.db
        !           104:   forcedelete corrupt.db-journal
        !           105:   forcecopy test.db corrupt.db
        !           106:   set f [open corrupt.db RDWR]
        !           107:   fconfigure $f -encoding binary
        !           108:   seek $f 101 start
        !           109:   puts -nonewline $f "\x00\xC8"
        !           110:   seek $f 200 start
        !           111:   puts -nonewline $f "\x00\x00"
        !           112:   puts -nonewline $f "\x10\x00"
        !           113:   close $f
        !           114: 
        !           115:   sqlite3 db2 corrupt.db
        !           116:   catchsql "
        !           117:     $::presql
        !           118:     SELECT * FROM sqlite_master;
        !           119:   " db2
        !           120: } {1 {database disk image is malformed}}
        !           121: db2 close
        !           122: 
        !           123: # Corrupt a database by having 2 indices of the same name:
        !           124: do_test corrupt2-2.1 {
        !           125: 
        !           126:   forcedelete corrupt.db
        !           127:   forcedelete corrupt.db-journal
        !           128:   forcecopy test.db corrupt.db
        !           129: 
        !           130:   sqlite3 db2 corrupt.db 
        !           131:   execsql "
        !           132:     $::presql
        !           133:     CREATE INDEX a1 ON abc(a);
        !           134:     CREATE INDEX a2 ON abc(b);
        !           135:     PRAGMA writable_schema = 1;
        !           136:     UPDATE sqlite_master 
        !           137:       SET name = 'a3', sql = 'CREATE INDEX a3' || substr(sql, 16, 10000)
        !           138:       WHERE type = 'index';
        !           139:     PRAGMA writable_schema = 0;
        !           140:   " db2
        !           141: 
        !           142:   db2 close
        !           143:   sqlite3 db2 corrupt.db 
        !           144:   catchsql "
        !           145:     $::presql
        !           146:     SELECT * FROM sqlite_master;
        !           147:   " db2
        !           148: } {1 {malformed database schema (a3) - index a3 already exists}}
        !           149: 
        !           150: db2 close
        !           151: 
        !           152: do_test corrupt2-3.1 {
        !           153:   forcedelete corrupt.db
        !           154:   forcedelete corrupt.db-journal
        !           155:   sqlite3 db2 corrupt.db 
        !           156: 
        !           157:   execsql "
        !           158:     $::presql
        !           159:     PRAGMA auto_vacuum = 1;
        !           160:     PRAGMA page_size = 1024;
        !           161:     CREATE TABLE t1(a, b, c);
        !           162:     CREATE TABLE t2(a, b, c);
        !           163:     INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100));
        !           164:     INSERT INTO t2 SELECT * FROM t2;
        !           165:     INSERT INTO t2 SELECT * FROM t2;
        !           166:     INSERT INTO t2 SELECT * FROM t2;
        !           167:     INSERT INTO t2 SELECT * FROM t2;
        !           168:   " db2
        !           169: 
        !           170:   db2 close
        !           171: 
        !           172:   # On the root page of table t2 (page 4), set one of the child page-numbers
        !           173:   # to 0. This corruption will be detected when SQLite attempts to update
        !           174:   # the pointer-map after moving the content of page 4 to page 3 as part
        !           175:   # of the DROP TABLE operation below.
        !           176:   #
        !           177:   set fd [open corrupt.db r+]
        !           178:   fconfigure $fd -encoding binary -translation binary
        !           179:   seek $fd [expr 1024*3 + 12]
        !           180:   set zCelloffset [read $fd 2]
        !           181:   binary scan $zCelloffset S iCelloffset
        !           182:   seek $fd [expr 1024*3 + $iCelloffset]
        !           183:   puts -nonewline $fd "\00\00\00\00" 
        !           184:   close $fd
        !           185: 
        !           186:   sqlite3 db2 corrupt.db 
        !           187:   catchsql "
        !           188:     $::presql
        !           189:     DROP TABLE t1;
        !           190:   " db2
        !           191: } {1 {database disk image is malformed}}
        !           192: 
        !           193: do_test corrupt2-4.1 {
        !           194:   catchsql {
        !           195:     SELECT * FROM t2;
        !           196:   } db2
        !           197: } {1 {database disk image is malformed}}
        !           198: 
        !           199: db2 close
        !           200: 
        !           201: unset -nocomplain result
        !           202: do_test corrupt2-5.1 {
        !           203:   forcedelete corrupt.db
        !           204:   forcedelete corrupt.db-journal
        !           205:   sqlite3 db2 corrupt.db 
        !           206: 
        !           207:   execsql "
        !           208:     $::presql
        !           209:     PRAGMA auto_vacuum = 0;
        !           210:     PRAGMA page_size = 1024;
        !           211:     CREATE TABLE t1(a, b, c);
        !           212:     CREATE TABLE t2(a, b, c);
        !           213:     INSERT INTO t2 VALUES(randomblob(100), randomblob(100), randomblob(100));
        !           214:     INSERT INTO t2 SELECT * FROM t2;
        !           215:     INSERT INTO t2 SELECT * FROM t2;
        !           216:     INSERT INTO t2 SELECT * FROM t2;
        !           217:     INSERT INTO t2 SELECT * FROM t2;
        !           218:     INSERT INTO t1 SELECT * FROM t2;
        !           219:   " db2
        !           220: 
        !           221:   db2 close
        !           222: 
        !           223:   # This block links a page from table t2 into the t1 table structure.
        !           224:   #
        !           225:   set fd [open corrupt.db r+]
        !           226:   fconfigure $fd -encoding binary -translation binary
        !           227:   seek $fd [expr 1024 + 12]
        !           228:   set zCelloffset [read $fd 2]
        !           229:   binary scan $zCelloffset S iCelloffset
        !           230:   seek $fd [expr 1024 + $iCelloffset]
        !           231:   set zChildPage [read $fd 4]
        !           232:   seek $fd [expr 2*1024 + 12]
        !           233:   set zCelloffset [read $fd 2]
        !           234:   binary scan $zCelloffset S iCelloffset
        !           235:   seek $fd [expr 2*1024 + $iCelloffset]
        !           236:   puts -nonewline $fd $zChildPage
        !           237:   close $fd
        !           238: 
        !           239:   sqlite3 db2 corrupt.db 
        !           240:   db2 eval $::presql
        !           241:   db2 eval {SELECT rowid FROM t1} {
        !           242:     set result [db2 eval {pragma integrity_check}]
        !           243:     break
        !           244:   }
        !           245:   set result
        !           246: } {{*** in database main ***
        !           247: On tree page 2 cell 0: 2nd reference to page 10
        !           248: On tree page 2 cell 1: Child page depth differs
        !           249: Page 4 is never used}}
        !           250: 
        !           251: db2 close
        !           252: 
        !           253: proc corruption_test {args} {
        !           254:   set A(-corrupt) {}
        !           255:   set A(-sqlprep) {}
        !           256:   set A(-tclprep) {}
        !           257:   array set A $args
        !           258: 
        !           259:   catch {db close}
        !           260:   forcedelete corrupt.db
        !           261:   forcedelete corrupt.db-journal
        !           262: 
        !           263:   sqlite3 db corrupt.db 
        !           264:   db eval $::presql
        !           265:   eval $A(-tclprep)
        !           266:   db eval $A(-sqlprep)
        !           267:   db close
        !           268: 
        !           269:   eval $A(-corrupt)
        !           270: 
        !           271:   sqlite3 db corrupt.db
        !           272:   eval $A(-test)
        !           273: }
        !           274: 
        !           275: ifcapable autovacuum {
        !           276:   # The tests within this block - corrupt2-6.* - aim to test corruption
        !           277:   # detection within an incremental-vacuum. When an incremental-vacuum
        !           278:   # step is executed, the last non-free page of the database file is 
        !           279:   # moved into a free space in the body of the file. After doing so,
        !           280:   # the page reference in the parent page must be updated to refer
        !           281:   # to the new location. These tests test the outcome of corrupting
        !           282:   # that page reference before performing the incremental vacuum.
        !           283:   #
        !           284: 
        !           285:   # The last page in the database page is the second page 
        !           286:   # in an overflow chain.
        !           287:   #
        !           288:   corruption_test -sqlprep {
        !           289:     PRAGMA auto_vacuum = incremental;
        !           290:     PRAGMA page_size = 1024;
        !           291:     CREATE TABLE t1(a, b);
        !           292:     INSERT INTO t1 VALUES(1, randomblob(2500));
        !           293:     INSERT INTO t1 VALUES(2, randomblob(2500));
        !           294:     DELETE FROM t1 WHERE a = 1;
        !           295:   } -corrupt {
        !           296:     hexio_write corrupt.db [expr 1024*5] 00000008
        !           297:   } -test {
        !           298:     do_test corrupt2-6.1 {
        !           299:       catchsql " $::presql pragma incremental_vacuum = 1 "
        !           300:     } {1 {database disk image is malformed}}
        !           301:   }
        !           302: 
        !           303:   # The last page in the database page is a non-root b-tree page.
        !           304:   #
        !           305:   corruption_test -sqlprep {
        !           306:     PRAGMA auto_vacuum = incremental;
        !           307:     PRAGMA page_size = 1024;
        !           308:     CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           309:     INSERT INTO t1 VALUES(1, randomblob(2500));
        !           310:     INSERT INTO t1 VALUES(2, randomblob(50));
        !           311:     INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           312:     INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           313:     INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           314:     INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           315:     DELETE FROM t1 WHERE a = 1;
        !           316:   } -corrupt {
        !           317:     hexio_write corrupt.db [expr 1024*2 + 8] 00000009
        !           318:   } -test {
        !           319:     do_test corrupt2-6.2 {
        !           320:       catchsql " $::presql pragma incremental_vacuum = 1 "
        !           321:     } {1 {database disk image is malformed}}
        !           322:   }
        !           323: 
        !           324:   # Set up a pointer-map entry so that the last page of the database
        !           325:   # file appears to be a b-tree root page. This should be detected
        !           326:   # as corruption.
        !           327:   #
        !           328:   corruption_test -sqlprep {
        !           329:     PRAGMA auto_vacuum = incremental;
        !           330:     PRAGMA page_size = 1024;
        !           331:     CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           332:     INSERT INTO t1 VALUES(1, randomblob(2500));
        !           333:     INSERT INTO t1 VALUES(2, randomblob(2500));
        !           334:     INSERT INTO t1 VALUES(3, randomblob(2500));
        !           335:     DELETE FROM t1 WHERE a = 1;
        !           336:   } -corrupt {
        !           337:     set nPage [expr [file size corrupt.db] / 1024]
        !           338:     hexio_write corrupt.db [expr 1024 + ($nPage-3)*5] 010000000
        !           339:   } -test {
        !           340:     do_test corrupt2-6.3 {
        !           341:       catchsql " $::presql pragma incremental_vacuum = 1 "
        !           342:     } {1 {database disk image is malformed}}
        !           343:   }
        !           344: 
        !           345:   corruption_test -sqlprep {
        !           346:     PRAGMA auto_vacuum = 1;
        !           347:     PRAGMA page_size = 1024;
        !           348:     CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           349:     INSERT INTO t1 VALUES(1, randomblob(2500));
        !           350:     DELETE FROM t1 WHERE a = 1;
        !           351:   } -corrupt {
        !           352:     set nAppend [expr 1024*207 - [file size corrupt.db]]
        !           353:     set fd [open corrupt.db r+]
        !           354:     seek $fd 0 end
        !           355:     puts -nonewline $fd [string repeat x $nAppend]
        !           356:     close $fd
        !           357:     hexio_write corrupt.db 28 00000000
        !           358:   } -test {
        !           359:     do_test corrupt2-6.4 {
        !           360:       catchsql " 
        !           361:         $::presql 
        !           362:         BEGIN EXCLUSIVE;
        !           363:         COMMIT;
        !           364:       "
        !           365:     } {1 {database disk image is malformed}}
        !           366:   }
        !           367: }
        !           368: 
        !           369: 
        !           370: set sqlprep {
        !           371:   PRAGMA auto_vacuum = 0;
        !           372:   PRAGMA page_size = 1024;
        !           373:   CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           374:   CREATE INDEX i1 ON t1(b);
        !           375:   INSERT INTO t1 VALUES(1, randomblob(50));
        !           376:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           377:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           378:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           379:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           380:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           381:   INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
        !           382: }
        !           383: 
        !           384: corruption_test -sqlprep $sqlprep -corrupt {
        !           385:   # Set the page-flags of one of the leaf pages of the index B-Tree to
        !           386:   # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree").
        !           387:   #
        !           388:   set fd [open corrupt.db r+]
        !           389:   fconfigure $fd -translation binary -encoding binary
        !           390:   seek $fd [expr 1024*2 + 8] 
        !           391:   set zRightChild [read $fd 4]
        !           392:   binary scan $zRightChild I iRightChild
        !           393:   seek $fd [expr 1024*($iRightChild-1)]
        !           394:   puts -nonewline $fd "\x0D"
        !           395:   close $fd
        !           396: } -test {
        !           397:   do_test corrupt2-7.1 {
        !           398:     catchsql " $::presql SELECT b FROM t1 ORDER BY b ASC "
        !           399:   } {1 {database disk image is malformed}}
        !           400: }
        !           401: 
        !           402: corruption_test -sqlprep $sqlprep -corrupt {
        !           403:   # Mess up the page-header of one of the leaf pages of the index B-Tree.
        !           404:   # The corruption is detected as part of an OP_Prev opcode.
        !           405:   #
        !           406:   set fd [open corrupt.db r+]
        !           407:   fconfigure $fd -translation binary -encoding binary
        !           408:   seek $fd [expr 1024*2 + 12] 
        !           409:   set zCellOffset [read $fd 2]
        !           410:   binary scan $zCellOffset S iCellOffset
        !           411:   seek $fd [expr 1024*2 + $iCellOffset]
        !           412:   set zChild [read $fd 4]
        !           413:   binary scan $zChild I iChild
        !           414:   seek $fd [expr 1024*($iChild-1)+3]
        !           415:   puts -nonewline $fd "\xFFFF"
        !           416:   close $fd
        !           417: } -test {
        !           418:   do_test corrupt2-7.1 {
        !           419:     catchsql " $::presql SELECT b FROM t1 ORDER BY b DESC "
        !           420:   } {1 {database disk image is malformed}}
        !           421: }
        !           422: 
        !           423: corruption_test -sqlprep $sqlprep -corrupt {
        !           424:   # Set the page-flags of one of the leaf pages of the table B-Tree to
        !           425:   # 0x0A (interpreted by SQLite as "leaf page of an index B-Tree").
        !           426:   #
        !           427:   set fd [open corrupt.db r+]
        !           428:   fconfigure $fd -translation binary -encoding binary
        !           429:   seek $fd [expr 1024*1 + 8] 
        !           430:   set zRightChild [read $fd 4]
        !           431:   binary scan $zRightChild I iRightChild
        !           432:   seek $fd [expr 1024*($iRightChild-1)]
        !           433:   puts -nonewline $fd "\x0A"
        !           434:   close $fd
        !           435: } -test {
        !           436:   do_test corrupt2-8.1 {
        !           437:     catchsql " $::presql SELECT * FROM t1 WHERE rowid=1000 "
        !           438:   } {1 {database disk image is malformed}}
        !           439: }
        !           440: 
        !           441: corruption_test -sqlprep {
        !           442:   CREATE TABLE t1(a, b, c); CREATE TABLE t8(a, b, c); CREATE TABLE tE(a, b, c);
        !           443:   CREATE TABLE t2(a, b, c); CREATE TABLE t9(a, b, c); CREATE TABLE tF(a, b, c);
        !           444:   CREATE TABLE t3(a, b, c); CREATE TABLE tA(a, b, c); CREATE TABLE tG(a, b, c);
        !           445:   CREATE TABLE t4(a, b, c); CREATE TABLE tB(a, b, c); CREATE TABLE tH(a, b, c);
        !           446:   CREATE TABLE t5(a, b, c); CREATE TABLE tC(a, b, c); CREATE TABLE tI(a, b, c);
        !           447:   CREATE TABLE t6(a, b, c); CREATE TABLE tD(a, b, c); CREATE TABLE tJ(a, b, c);
        !           448:   CREATE TABLE x1(a, b, c); CREATE TABLE x8(a, b, c); CREATE TABLE xE(a, b, c);
        !           449:   CREATE TABLE x2(a, b, c); CREATE TABLE x9(a, b, c); CREATE TABLE xF(a, b, c);
        !           450:   CREATE TABLE x3(a, b, c); CREATE TABLE xA(a, b, c); CREATE TABLE xG(a, b, c);
        !           451:   CREATE TABLE x4(a, b, c); CREATE TABLE xB(a, b, c); CREATE TABLE xH(a, b, c);
        !           452:   CREATE TABLE x5(a, b, c); CREATE TABLE xC(a, b, c); CREATE TABLE xI(a, b, c);
        !           453:   CREATE TABLE x6(a, b, c); CREATE TABLE xD(a, b, c); CREATE TABLE xJ(a, b, c);
        !           454: } -corrupt {
        !           455:   set fd [open corrupt.db r+]
        !           456:   fconfigure $fd -translation binary -encoding binary
        !           457:   seek $fd 108
        !           458:   set zRightChild [read $fd 4]
        !           459:   binary scan $zRightChild I iRightChild
        !           460:   seek $fd [expr 1024*($iRightChild-1)+3]
        !           461:   puts -nonewline $fd "\x00\x00"
        !           462:   close $fd
        !           463: } -test {
        !           464:   do_test corrupt2-9.1 {
        !           465:     catchsql " $::presql SELECT sql FROM sqlite_master "
        !           466:   } {1 {database disk image is malformed}}
        !           467: }
        !           468: 
        !           469: corruption_test -sqlprep {
        !           470:   CREATE TABLE t1(a, b, c);
        !           471:   CREATE TABLE t2(a, b, c);
        !           472:   PRAGMA writable_schema = 1;
        !           473:   UPDATE sqlite_master SET rootpage = NULL WHERE name = 't2';
        !           474: } -test {
        !           475:   do_test corrupt2-10.1 {
        !           476:     catchsql " $::presql SELECT * FROM t2 "
        !           477:   } {1 {malformed database schema (t2)}}
        !           478:   do_test corrupt2-10.2 {
        !           479:     sqlite3_errcode db
        !           480:   } {SQLITE_CORRUPT}
        !           481: }
        !           482: 
        !           483: corruption_test -sqlprep {
        !           484:   PRAGMA auto_vacuum = incremental;
        !           485:   CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           486:   CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
        !           487:   INSERT INTO t1 VALUES(1, randstr(100,100));
        !           488:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           489:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           490:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           491:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           492:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           493:   INSERT INTO t2 SELECT * FROM t1;
        !           494:   DELETE FROM t1;
        !           495: } -corrupt {
        !           496:   set offset [expr [file size corrupt.db] - 1024]
        !           497:   hexio_write corrupt.db $offset FF 
        !           498:   hexio_write corrupt.db 24   12345678
        !           499: } -test {
        !           500:   do_test corrupt2-11.1 {
        !           501:     catchsql " $::presql PRAGMA incremental_vacuum "
        !           502:   } {1 {database disk image is malformed}}
        !           503: }
        !           504: corruption_test -sqlprep {
        !           505:   PRAGMA auto_vacuum = incremental;
        !           506:   CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           507:   CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
        !           508:   INSERT INTO t1 VALUES(1, randstr(100,100));
        !           509:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           510:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           511:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           512:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           513:   INSERT INTO t1 SELECT NULL, randstr(100,100) FROM t1;
        !           514:   INSERT INTO t2 SELECT * FROM t1;
        !           515:   DELETE FROM t1;
        !           516: } -corrupt {
        !           517:   set pgno [expr [file size corrupt.db] / 1024]
        !           518:   hexio_write corrupt.db [expr 1024+5*($pgno-3)] 03 
        !           519:   hexio_write corrupt.db 24   12345678
        !           520: } -test {
        !           521:   do_test corrupt2-12.1 {
        !           522:     catchsql " $::presql PRAGMA incremental_vacuum "
        !           523:   } {1 {database disk image is malformed}}
        !           524: }
        !           525: 
        !           526: ifcapable autovacuum {
        !           527:   # It is not possible for the last page in a database file to be the
        !           528:   # pending-byte page (AKA the locking page). This test verifies that if
        !           529:   # an attempt is made to commit a transaction to such an auto-vacuum 
        !           530:   # database SQLITE_CORRUPT is returned.
        !           531:   #
        !           532:   corruption_test -tclprep {
        !           533:     db eval { 
        !           534:       PRAGMA auto_vacuum = full;
        !           535:       PRAGMA page_size = 1024;
        !           536:       CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
        !           537:       INSERT INTO t1 VALUES(NULL, randstr(50,50));
        !           538:     }
        !           539:     for {set ii 0} {$ii < 10} {incr ii} {
        !           540:       db eval " $::presql INSERT INTO t1 SELECT NULL, randstr(50,50) FROM t1 "
        !           541:     }
        !           542:   } -corrupt {
        !           543:     do_test corrupt2-13.1 {
        !           544:       file size corrupt.db
        !           545:     } $::sqlite_pending_byte
        !           546:     hexio_write corrupt.db [expr $::sqlite_pending_byte+1023] 00
        !           547:     hexio_write corrupt.db 28 00000000
        !           548:   } -test {
        !           549:     do_test corrupt2-13.2 {
        !           550:       file size corrupt.db
        !           551:     } [expr $::sqlite_pending_byte + 1024]
        !           552:     do_test corrupt2-13.3 {
        !           553:       catchsql { DELETE FROM t1 WHERE rowid < 30; }
        !           554:     } {1 {database disk image is malformed}}
        !           555:   }
        !           556: }
        !           557: 
        !           558: finish_test

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