| # 2017-03-03 |
| # |
| # The author disclaims copyright to this source code. In place of |
| # a legal notice, here is a blessing: |
| # |
| # May you do good and not evil. |
| # May you find forgiveness for yourself and forgive others. |
| # May you share freely, never taking more than you give. |
| # |
| #*********************************************************************** |
| # |
| |
| set testdir [file dirname $argv0] |
| source $testdir/tester.tcl |
| set testprefix corruptK |
| |
| if {[permutation]=="mmap"} { |
| finish_test |
| return |
| } |
| |
| # This module uses hard-coded offsets which do not work if the reserved_bytes |
| # value is nonzero. |
| if {[nonzero_reserved_bytes]} {finish_test; return;} |
| database_may_be_corrupt |
| |
| # Initialize the database. |
| # |
| do_execsql_test 1.1 { |
| PRAGMA page_size=1024; |
| PRAGMA auto_vacuum=0; |
| CREATE TABLE t1(x); |
| |
| INSERT INTO t1 VALUES(randomblob(20)); |
| INSERT INTO t1 VALUES(randomblob(100)); -- make this into a free slot |
| INSERT INTO t1 VALUES(randomblob(27)); -- this one will be corrupt |
| INSERT INTO t1 VALUES(randomblob(800)); |
| |
| DELETE FROM t1 WHERE rowid=2; -- free the 100 byte slot |
| PRAGMA page_count |
| } {2} |
| |
| |
| # Corrupt the database so that the blob stored immediately before |
| # the free slot (rowid==3) has an overlarge length field. So that |
| # we can use sqlite3_blob_write() to manipulate the size field of |
| # the free slot. |
| # |
| # Then use sqlite3_blob_write() to set the size of said free slot |
| # to 24 bytes (instead of the actual 100). |
| # |
| # Then use the new 24 byte slot. Leaving the in-memory version of |
| # the page with zero free slots and a large nFree value. Then try |
| # to allocate another slot to get to defragmentPage(). |
| # |
| do_test 1.2 { |
| db close |
| hexio_write test.db [expr 1024 + 0x360] 21 |
| hexio_write test.db [expr 1024 + 0x363] [format %x [expr 31*2 + 12]] |
| sqlite3 db test.db |
| |
| set fd [db incrblob t1 x 3] |
| fconfigure $fd -translation binary -encoding binary |
| seek $fd 30 |
| puts -nonewline $fd "\x18" |
| close $fd |
| } {} |
| do_execsql_test 1.3 { |
| INSERT INTO t1 VALUES(randomblob(20)); |
| } |
| do_catchsql_test 1.4 { |
| INSERT INTO t1 VALUES(randomblob(90)); |
| } {1 {database disk image is malformed}} |
| |
| #------------------------------------------------------------------------- |
| reset_db |
| do_execsql_test 2.1 { |
| PRAGMA page_size=1024; |
| PRAGMA auto_vacuum=0; |
| CREATE TABLE t1(x); |
| |
| INSERT INTO t1 VALUES(randomblob(20)); |
| INSERT INTO t1 VALUES(randomblob(20)); -- free this one |
| INSERT INTO t1 VALUES(randomblob(20)); |
| INSERT INTO t1 VALUES(randomblob(20)); -- and this one |
| INSERT INTO t1 VALUES(randomblob(20)); -- corrupt this one. |
| |
| DELETE FROM t1 WHERE rowid IN(2, 4); |
| PRAGMA page_count |
| } {2} |
| |
| do_test 2.2 { |
| db close |
| hexio_write test.db [expr 1024 + 0x388] 53 |
| hexio_write test.db [expr 1024 + 0x38A] 03812C |
| |
| sqlite3 db test.db |
| set fd [db incrblob t1 x 5] |
| fconfigure $fd -translation binary -encoding binary |
| |
| seek $fd 22 |
| puts -nonewline $fd "\x5d" |
| close $fd |
| } {} |
| |
| do_catchsql_test 2.3 { |
| INSERT INTO t1 VALUES(randomblob(900)); |
| } {1 {database disk image is malformed}} |
| |
| |
| |
| |
| finish_test |