Adding the sqlite sourcecode

This commit is contained in:
Jiří Stach committed 2025-07-17 11:54:48 +02:00
1 parent bdb54a1f8f
commit 406b584760
2208 files changed
+1172785 -1

No files matched your search

+1023
View File
File diff suppressed because it is too large. Load diff
+377
View File
@@ -0,0 +1,377 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recover1
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
compare_result $db1 $db2 "PRAGMA page_size"
compare_result $db1 $db2 "PRAGMA auto_vacuum"
compare_result $db1 $db2 "PRAGMA encoding"
compare_result $db1 $db2 "PRAGMA user_version"
compare_result $db1 $db2 "PRAGMA application_id"
}
proc do_recover_test {tn} {
forcedelete test.db2
forcedelete rstate.db
uplevel [list do_test $tn.1 {
set R [sqlite3_recover_init db main test.db2]
$R config testdb rstate.db
$R run
$R finish
} {}]
sqlite3 db2 test.db2
uplevel [list do_test $tn.2 [list compare_dbs db db2] {}]
db2 close
forcedelete test.db2
forcedelete rstate.db
uplevel [list do_test $tn.3 {
set ::sqlhook [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config testdb rstate.db
$R config rowids 1
$R run
$R finish
} {}]
sqlite3 db2 test.db2
execsql [join $::sqlhook ";"] db2
db2 close
sqlite3 db2 test.db2
uplevel [list do_test $tn.4 [list compare_dbs db db2] {}]
db2 close
}
proc my_sql_hook {sql} {
lappend ::sqlhook $sql
return 0
}
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
)
INSERT INTO t1 SELECT i*2, hex(randomblob(250)) FROM s;
INSERT INTO t2 SELECT * FROM t1;
}
do_recover_test 1
do_execsql_test 2.0 {
ALTER TABLE t1 ADD COLUMN c DEFAULT 'xyz'
}
do_recover_test 2
do_execsql_test 3.0 {
CREATE INDEX i1 ON t1(c);
}
do_recover_test 3
do_execsql_test 4.0 {
CREATE VIEW v1 AS SELECT * FROM t2;
}
do_recover_test 4
do_execsql_test 5.0 {
CREATE UNIQUE INDEX i2 ON t1(c, b);
}
do_recover_test 5
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INT,
c TEXT,
d INT GENERATED ALWAYS AS (a*abs(b)) VIRTUAL,
e TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED,
f TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED
);
INSERT INTO t1 VALUES(1, 2, 'hello world');
}
do_recover_test 6
do_execsql_test 7.0 {
CREATE TABLE t2(i, j GENERATED ALWAYS AS (i+1) STORED, k);
INSERT INTO t2 VALUES(10, 'ten');
}
do_execsql_test 7.1 {
SELECT * FROM t2
} {10 11 ten}
do_recover_test 7.2
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.0 {
CREATE TABLE x1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<2
)
INSERT INTO x1(b, c) SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s;
CREATE INDEX x1b ON x1(b);
CREATE INDEX x1cb ON x1(c, b);
DELETE FROM x1 WHERE a>50;
ANALYZE;
}
do_recover_test 8
#-------------------------------------------------------------------------
reset_db
ifcapable fts5 {
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE ft5 USING fts5(a, b);
INSERT INTO ft5 VALUES('hello', 'world');
}
do_recover_test 9
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.1 {
CREATE TABLE x1(a PRIMARY KEY, str TEXT) WITHOUT ROWID;
INSERT INTO x1 VALUES(1, '
\nhello\012world(\n0)(\n1)
');
INSERT INTO x1 VALUES(2, '
\nhello
');
}
do_execsql_test 10.2 "
INSERT INTO x1 VALUES(3, '\012hello there\015world');
INSERT INTO x1 VALUES(4, '\015hello there\015world');
"
do_recover_test 10
#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.1 {
PRAGMA page_size = 4096;
PRAGMA encoding='utf16';
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
INSERT INTO u1 VALUES('edvin marton', 'bond');
INSERT INTO u1 VALUES(1, 4.0);
}
do_execsql_test 11.1a {
PRAGMA auto_vacuum;
} {2}
do_recover_test 11
do_test 12.1 {
set R [sqlite3_recover_init db "" test.db2]
$R config lostandfound ""
$R config invalid xyz
} {12}
do_test 12.2 {
$R run
$R run
} {0}
do_test 12.3 {
$R finish
} {}
#-------------------------------------------------------------------------
reset_db
file_control_reservebytes db 16
do_execsql_test 12.1 {
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
CREATE UNIQUE INDEX i1 ON u1(u, v);
INSERT INTO u1 VALUES(1, 2), (3, 4);
CREATE TABLE u2(u, v);
CREATE UNIQUE INDEX i2 ON u1(u, v);
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
}
do_recover_test 12
#-------------------------------------------------------------------------
reset_db
sqlite3 db ""
do_recover_test 13
do_execsql_test 14.1 {
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
CREATE UNIQUE INDEX i1 ON u1(u, v);
INSERT INTO u1 VALUES(1, 2), (3, 4);
CREATE TABLE u2(u, v);
CREATE UNIQUE INDEX i2 ON u1(u, v);
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
}
do_recover_test 14
#-------------------------------------------------------------------------
reset_db
execsql {
PRAGMA journal_mode=OFF;
PRAGMA mmap_size=10;
}
do_execsql_test 15.1 {
CREATE TABLE t1(x);
} {}
do_recover_test 15
#-------------------------------------------------------------------------
reset_db
do_test 16.1 {
execsql { PRAGMA journal_mode = wal }
execsql {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1), (2), (3);
}
} {}
do_test 16.2 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
do_execsql_test 16.3 {
SELECT * FROM t1;
} {1 2 3}
do_execsql_test 16.4 {
BEGIN;
SELECT * FROM t1;
} {1 2 3}
do_test 16.5 {
set R [sqlite3_recover_init db main test.db2]
$R run
list [catch { $R finish } msg] $msg
} {1 {cannot start a transaction within a transaction}}
do_execsql_test 16.6 {
SELECT * FROM t1;
} {1 2 3}
do_execsql_test 16.7 {
INSERT INTO t1 VALUES(4);
}
do_test 16.8 {
set R [sqlite3_recover_init db main test.db2]
$R run
list [catch { $R finish } msg] $msg
} {1 {cannot start a transaction within a transaction}}
do_execsql_test 16.9 {
SELECT * FROM t1;
COMMIT;
} {1 2 3 4}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.1 {
CREATE TABLE t(a, PRIMARY KEY(a, a COLLATE NOCASE)) WITHOUT ROWID;
INSERT INTO t VALUES('abc');
INSERT INTO t VALUES('def');
}
do_test 17.2 {
set R [sqlite3_recover_init db main test.db2]
$R run
list [catch { $R finish } msg] $msg
} {0 {}}
#-------------------------------------------------------------------------
foreach enc {utf8 utf16 utf16le utf16be} {
reset_db
do_execsql_test 18.$enc.1 {
PRAGMA auto_vacuum = 0;
PRAGMA encoding='utf16';
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t1 VALUES('abc', 'def');
PRAGMA writable_schema = 1;
DELETE FROM sqlite_schema WHERE name='t1';
}
proc my_sql_hook2 {sql} {
if {[string match "INSERT INTO lostandfound*" $sql]} {
lappend ::script $sql
}
return 0
}
do_test 18.$enc.2 {
set ::script [list]
set R [sqlite3_recover_init_sql db main my_sql_hook2]
$R config lostandfound lostandfound
$R run
$R finish
set ::script
} {{INSERT INTO lostandfound VALUES(2, 2, 2, 1, 'abc', 'def')}}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 19.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
ALTER TABLE t1 ADD COLUMN c NOT NULL DEFAULT 13;
INSERT INTO t1 VALUES(3, 'three', 'hello world');
}
do_recover_test 19.1
finish_test
+14
View File
@@ -0,0 +1,14 @@
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
if {[info commands sqlite3_recover_init]==""} {
finish_test
return -code return
}
+42
View File
@@ -0,0 +1,42 @@
# 2023 February 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverbuild
# The following tests verify that if the recovery extension is used with
# a build that does not support the sqlite_dbpage table, the error message
# is "no such table: sqlite_dbpage", and not something more generic.
#
reset_db
create_null_module db sqlite_dbpage
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
INSERT INTO t1 VALUES(123, 'one hundred and twenty three');
}
forcedelete test.db2
do_test 1.1 {
set R [sqlite3_recover_init db main test.db2]
} {/sqlite_recover.*/}
do_test 1.2 {
$R run
} {1}
do_test 1.3 {
list [catch { $R finish } msg] $msg
} {1 {no such table: sqlite_dbpage}}
finish_test
+50
View File
@@ -0,0 +1,50 @@
# 2019 April 23
#
# 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.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_ROWIDS option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverclobber
proc recover {db output} {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
}
forcedelete test.db2
do_execsql_test 1.0 {
ATTACH 'test.db2' AS aux;
CREATE TABLE aux.x1(x, one);
INSERT INTO x1 VALUES(1, 'one'), (2, 'two'), (3, 'three');
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
DETACH aux;
}
breakpoint
do_test 1.1 {
recover db test.db2
} {}
do_execsql_test 1.2 {
ATTACH 'test.db2' AS aux;
SELECT * FROM aux.t1;
} {1 1 2 2 3 3 4 4}
do_catchsql_test 1.3 {
SELECT * FROM aux.x1;
} {1 {no such table: aux.x1}}
finish_test
+67
View File
@@ -0,0 +1,67 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt
database_may_be_corrupt
do_execsql_test 1.0 {
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(100)), randomblob(200));
CREATE INDEX i1 ON t1(b, c);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(100)), randomblob(200));
ANALYZE;
PRAGMA writable_schema = 1;
DELETE FROM sqlite_schema WHERE name='t2';
}
do_test 1.1 {
expr [file size test.db]>3072
} {1}
proc toggle_bit {blob bit} {
set byte [expr {$bit / 8}]
set bit [expr {$bit & 0x0F}]
binary scan $blob a${byte}ca* A x B
set x [expr {$x ^ (1 << $bit)}]
binary format a*ca* $A $x $B
}
db_save_and_close
for {set ii 0} {$ii < 10000} {incr ii} {
db_restore_and_reopen
db func toggle_bit toggle_bit
set bitsperpage [expr 512*8]
set pg [expr {($ii / $bitsperpage)+1}]
set byte [expr {$ii % $bitsperpage}]
db eval {
UPDATE sqlite_dbpage SET data = toggle_bit(data, $byte) WHERE pgno=$pg
}
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
do_test 1.2.$ii {
$R finish
} {}
}
finish_test
+608
View File
@@ -0,0 +1,608 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt2
do_execsql_test 1.0 {
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(100)), randomblob(200));
CREATE INDEX i1 ON t1(b, c);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(100)), randomblob(200));
ANALYZE;
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET sql = 'CREATE INDEX i1 ON o(world)' WHERE name='i1';
DELETE FROM sqlite_schema WHERE name='sqlite_stat4';
}
do_test 1.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 1.2 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c)}
{CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID}
{CREATE TABLE sqlite_stat1(tbl,idx,stat)}
}
db2 close
do_execsql_test 1.3 {
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET sql = 'CREATE TABLE t2 syntax error!' WHERE name='t2';
}
do_test 1.4 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 1.5 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c)}
{CREATE TABLE sqlite_stat1(tbl,idx,stat)}
}
db2 close
#-------------------------------------------------------------------------
#
reset_db
do_test 2.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename x3.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 63 00 0d 00 00 00 01 0f d8 00 0f d8 00 00 ..c.............
| 4048: 00 00 00 00 00 00 00 00 26 01 06 17 11 11 01 39 ........&......9
| 4064: 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 54 45 tablet1t1.CREATE
| 4080: 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c 63 29 TABLE t1(a,b,c)
| page 2 offset 4096
| 0: 0d 00 00 00 01 0f ce 00 0f ce 00 00 00 00 00 00 ................
| 4032: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ..............(.
| 4048: ff ff ff ff ff ff ff 28 04 27 25 23 61 61 61 61 .........'%#aaaa
| 4064: 61 61 61 61 61 61 61 61 61 62 62 62 62 62 62 62 aaaaaaaaabbbbbbb
| 4080: 62 62 62 62 62 63 63 63 63 63 63 63 63 63 63 63 bbbbbccccccccccc
| end x3.db
}]} {}
do_test 2.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 2.2 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a,b,c)}
}
do_execsql_test -db db2 2.3 {
SELECT * FROM t1
} {}
db2 close
#-------------------------------------------------------------------------
#
reset_db
do_test 3.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 4096 pagesize 1024 filename corrupt032.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 04 00 01 01 08 40 20 20 00 00 00 02 00 00 00 03 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 24 80 0d 00 00 00 01 03 d4 00 03 d4 00 00 ..$.............
| 976: 00 00 00 00 22 01 06 17 11 11 01 31 74 61 62 6c ...........1tabl
| 992: 65 74 31 74 31 02 43 52 45 41 54 45 20 54 41 42 et1t1.CREATE TAB
| 1008: 4c 45 20 74 31 28 78 29 00 00 00 00 00 00 00 00 LE t1(x)........
| page 2 offset 1024
| 0: 0d 00 00 00 01 02 06 00 02 06 00 00 00 00 00 00 ................
| 512: 00 00 00 00 00 00 8b 60 01 03 97 46 00 00 00 00 .......`...F....
| 1008: 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 ................
| end corrupt032.txt.db
}]} {}
do_test 3.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
#-------------------------------------------------------------------------
#
reset_db
do_test 4.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 4096 pagesize 4096 filename crash-00f2d3627f1b43.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 00 01 01 02 00 40 20 20 01 00 ff 00 42 01 10 01 .....@ ....B...
| 32: ef 00 00 87 00 ff ff ff f0 01 01 10 ff ff 00 00 ................
| end crash-00f2d3627f1b43.db
}]} {}
do_test 4.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {1 {unable to open database file}}
#-------------------------------------------------------------------------
#
reset_db
do_test 5.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 16384 pagesize 4096 filename crash-7b75760a4c5f15.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 ................
| 96: 00 00 00 00 0d 00 00 00 03 0f 4e 00 0f bc 0f 90 ..........N.....
| 112: 0f 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .N..............
| 3904: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 03 ..............@.
| 3920: 06 17 11 11 01 6d 74 61 62 6c 65 74 32 74 32 04 .....mtablet2t2.
| 3936: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 CREATE TABLE t2(
| 3952: 78 2c 79 2c 7a 20 50 52 49 4d 41 52 59 20 4b 45 x,y,z PRIMARY KE
| 3968: 59 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 Y) WITHOUT ROWID
| 3984: 2a 02 06 17 13 11 01 3f 69 6e 64 65 78 74 31 61 *......?indext1a
| 4000: 74 31 03 43 52 45 41 54 45 20 49 4e 44 45 58 20 t1.CREATE INDEX
| 4016: 74 31 61 20 4f 4e 20 74 31 28 61 29 42 01 06 17 t1a ON t1(a)B...
| 4032: 11 11 01 71 74 61 62 6c 65 74 31 74 31 02 43 52 ...qtablet1t1.CR
| 4048: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 EATE TABLE t1(a
| 4064: 49 4e 54 2c 62 20 54 45 58 54 2c 63 20 42 4c 4f INT,b TEXT,c BLO
| 4080: 42 2c 64 20 52 45 41 4c 29 20 53 54 52 49 43 54 B,d REAL) STRICT
| page 2 offset 4096
| 0: 0d 00 00 00 14 0c ae 00 0f df 0f bd 0f 9a 0f 76 ...............v
| 16: 0f 51 0f 2b 0f 04 0e dc 0e b3 0e 89 0e 5e 0e 32 .Q.+.........^.2
| 32: 0e 05 0d 1a 0d a8 0d 78 0d 47 0d 15 0c e2 00 00 .......x.G......
| 3232: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 14 ..............2.
| 3248: 05 06 3f 34 07 15 f4 c9 23 af e2 b3 b6 61 62 63 ..?4....#....abc
| 3264: 30 32 30 78 79 7a 01 00 00 00 00 00 00 00 00 00 020xyz..........
| 3280: 00 00 00 00 00 00 00 00 00 00 c3 b0 96 7e fb 4e .............~.N
| 3296: c5 4c 31 13 05 06 1f 32 07 dd f2 2a a5 7e b2 4d .L1....2...*.~.M
| 3312: 82 61 62 63 30 31 39 78 79 7a 01 00 00 00 00 00 .abc019xyz......
| 3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 a3 d6 ................
| 3344: e9 f1 c2 fd f3 30 12 05 06 1f 30 07 8f 8f f5 c4 .....0....0.....
| 3360: 35 b6 7f 8d 61 62 63 30 31 38 00 00 00 00 00 00 5...abc018......
| 3376: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 ...............C
| 3392: b2 13 1f 9d 56 8a 47 21 b1 05 06 1f 2e 07 7f 46 ....V.G!.......F
| 3408: 91 03 3f 97 fb f7 61 62 63 30 00 00 00 00 00 00 ..?...abc0......
| 3440: c3 bb d8 96 86 c2 e8 2b 2e 10 05 06 1f 2c 07 6d .......+.....,.m
| 3456: 85 7b ce d0 32 d2 54 61 62 63 30 00 00 00 00 00 ....2.Tabc0.....
| 3488: 43 a1 eb 44 14 dc 03 7b 2d 0f 05 06 1f 2a 07 d9 C..D....-....*..
| 3504: ab ec bf 34 51 70 f3 61 62 63 30 31 35 78 79 7a ...4Qp.abc015xyz
| 3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 ................
| 3536: b6 3d f4 46 b1 6a af 2c 0e 05 06 1f 28 07 36 75 .=.F.j.,....(.6u
| 3552: e9 a2 bd 05 04 ea 61 62 63 30 31 34 78 79 7a 00 ......abc014xyz.
| 3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 ab 23 ...............#
| 3584: a7 6a 34 ca f8 2b 0d 05 06 1f 26 07 48 45 ab e0 .j4..+....&.HE..
| 3600: 8c 7c ff 0c 61 62 63 30 31 33 78 79 7a 00 00 00 .|..abc013xyz...
| 3616: 00 00 00 00 0d d0 00 00 00 00 43 b8 d3 93 f4 92 ..........C.....
| 3632: 5b 7a 2a 0c 05 06 1f 24 07 be 6d 1e db 61 5d 80 [z*....$..m..a].
| 3648: 9f 61 62 63 30 31 32 78 79 7a 00 00 00 00 00 00 .abc012xyz......
| 3664: 00 00 00 00 00 00 43 b5 a1 a4 af 7b c6 60 29 0b ......C......`).
| 3680: 05 06 1f 22 07 6e a2 a3 64 68 d4 a6 bd 61 62 63 .....n..dh...abc
| 3696: 30 31 31 78 79 7a 00 00 00 00 00 00 00 00 00 00 011xyz..........
| 3712: 00 c3 c4 1e ff 0f fc e6 ff 28 0a 05 06 1f 20 07 .........(.... .
| 3728: 50 f9 4a bb a5 7a 1e ca 61 62 63 30 31 30 78 79 P.J..z..abc010xy
| 3744: 7a 00 00 00 00 00 00 00 00 00 00 c3 a7 90 ed d9 z...............
| 3760: 5c 2c d5 27 09 05 06 1f 1e 07 90 8e 1d d9 1c 3a .,.'...........:
| 3776: e8 c1 61 62 63 30 30 39 78 79 7a 00 00 00 00 00 ..abc009xyz.....
| 3792: 00 00 00 00 43 a7 97 87 cf b0 ff 79 26 08 05 06 ....C......y&...
| 3808: 1f 1c 07 86 65 f6 7c 50 7a 2c 76 61 62 63 30 30 ....e.|Pz,vabc00
| 3824: 38 78 79 7a 00 00 00 00 00 00 00 00 c3 b0 e3 4c 8xyz...........L
| 3840: 4f d3 41 b5 25 07 05 06 1f 1a 07 8b 20 e5 68 11 O.A.%....... .h.
| 3856: 13 55 87 61 62 63 30 30 37 78 79 7a 00 00 00 00 .U.abc007xyz....
| 3872: 00 00 00 c3 b6 a3 74 f1 9c 33 f8 24 06 05 06 1f ......t..3.$....
| 3888: 18 07 97 3c bc 34 49 94 54 ab 61 62 63 30 30 36 ...<.4I.T.abc006
| 3904: 78 79 7a 00 00 00 00 00 00 c3 88 00 c2 ca 4c 4d xyz...........LM
| 3920: d3 23 05 05 06 1f 16 07 59 37 11 10 e9 e5 3d d5 .#......Y7....=.
| 3936: 61 62 63 30 30 35 78 79 7a 00 00 00 00 00 c3 c0 abc005xyz.......
| 3952: 15 12 67 ed 4b 79 22 04 05 06 1f 14 07 93 39 01 ..g.Ky........9.
| 3968: 7f b8 c7 99 58 61 62 63 30 30 34 78 79 7a 00 00 ....Xabc004xyz..
| 3984: 09 c0 43 bf e0 e7 6d 70 fd 61 21 03 05 06 1f 12 ..C...mp.a!.....
| 4000: 07 b6 df 8d 8b 27 08 22 5a 61 62 63 30 30 33 78 .....'..Zabc003x
| 4016: 79 7a 00 00 00 c3 c7 ea 0f dc dd 32 22 20 02 05 yz.........2. ..
| 4032: 06 1f 10 07 2f a6 da 71 df 66 b3 b5 61 62 63 30 ..../..q.f..abc0
| 4048: 30 32 78 79 7a 00 00 c3 ce d9 8d e9 ec 20 45 1f 02xyz........ E.
| 4064: 01 05 06 1f 0e 07 5a 47 53 20 3b 48 8f c0 61 62 ......ZGS ;H..ab
| 4080: 63 30 30 31 78 79 7a 00 c3 c9 e6 81 f8 d9 24 04 c001xyz.......$.
| page 3 offset 8192
| 0: 0a 00 00 00 14 0e fd 00 0f f3 0f e6 0f d9 0f cc ................
| 16: 0f bf 0f b2 0f a5 0f 98 0f 8b 0f 7e 0f 71 0f 64 ...........~.q.d
| 32: 0f 57 0f 4a 0f 3d 0f 30 0f 24 00 00 00 00 00 00 .W.J.=.0.$......
| 3824: 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 03 06 ................
| 3840: 01 7f 46 91 03 3f 97 fb f7 11 0c 03 06 01 6e a2 ..F..?........n.
| 3856: a3 64 68 d4 a6 bd 0b 0c 03 06 01 6d 85 7b ce d0 .dh........m....
| 3872: 32 d2 54 10 0b 03 06 09 5a 47 53 20 3b 48 8f c0 2.T.....ZGS ;H..
| 3888: 0c 03 06 01 59 37 11 10 e9 e5 3d d5 05 0c 03 06 ....Y7....=.....
| 3904: 01 50 f9 4a bb a5 7a 1e ca 0a 0c 03 06 01 48 45 .P.J..z.......HE
| 3920: ab e0 8c 7c ff 0c 0d 0c 03 06 01 36 75 e9 a2 bd ...|.......6u...
| 3936: 05 04 ea 0e 0c 03 06 01 2f a6 da 71 df 66 b3 b5 ......../..q.f..
| 3952: 02 0c 03 06 01 15 f4 c9 23 af e2 b3 b6 14 0c 03 ........#.......
| 3968: 06 01 dd f2 2a a5 7e b2 4d 82 13 0c 03 06 01 d9 ....*.~.M.......
| 3984: ab ec bf 34 51 70 f3 0f 0c 03 06 01 be 6d 1e db ...4Qp.......m..
| 4000: 61 5d 80 9f 0c 0c 03 06 01 b6 df 8d 8b 27 08 22 a]...........'..
| 4016: 5a 03 0c 03 06 01 97 3c bc 34 49 94 54 ab 06 0c Z......<.4I.T...
| 4032: 03 06 01 93 39 01 7f b8 c7 99 58 04 0c 03 06 01 ....9.....X.....
| 4048: 90 8e 1d d9 1c 3a e8 c1 09 0c 03 06 01 8f 8f f5 .....:..........
| 4064: c4 35 b6 7f 8d 12 0c 03 06 01 8b 20 e5 68 11 13 .5......... .h..
| 4080: 55 87 07 0c 03 06 01 86 65 f6 7c 50 7a 2b 06 08 U.......e.|Pz+..
| page 4 offset 12288
| 0: 0a 00 00 00 14 0f 62 00 0f 7a 0f a1 0f c9 0f d9 ......b..z......
| 16: 0f 81 0f d1 0f f1 0f f9 0f e1 0f 89 0e 6a 0f c1 .............j..
| 32: 0f 91 0f 99 0f b9 0f 72 0f 62 0f e9 0f b1 0f a9 .......r.b......
| 3936: 00 00 07 04 01 01 01 11 0e 9e 07 04 01 01 01 0b ................
| 3952: 31 16 07 04 01 01 01 10 37 36 06 04 09 01 01 ab 1.......76......
| 3968: 58 07 04 01 01 01 05 1c 28 07 04 01 01 01 0a 10 X.......(.......
| 3984: cf 07 04 01 01 01 0d b2 e3 07 04 01 01 01 0e d3 ................
| 4000: f2 07 04 01 01 01 02 41 ad 07 04 01 01 01 14 3e .......A.......>
| 4016: 22 07 04 01 01 01 13 27 45 07 04 01 01 01 0f ad .......'E.......
| 4032: dd 07 04 01 01 01 0c 2e a1 07 04 01 01 01 03 df ................
| 4048: e1 07 04 01 01 01 06 59 a7 07 04 01 01 01 04 27 .......Y.......'
| 4064: bd 07 04 01 01 01 09 d0 e0 07 04 01 01 01 12 39 ...............9
| 4080: 4f 07 04 01 01 01 07 c4 11 06 04 00 00 00 00 00 O...............
| end crash-7b75760a4c5f15.db
}]} {}
do_test 5.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
#-------------------------------------------------------------------------
#
reset_db
do_test 6.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename abc.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 6e b8 0d 00 00 00 01 0f dc 00 0f dc 00 00 ..n.............
| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 22 01 06 17 ................
| 4064: 11 11 01 31 74 61 62 6c 65 74 31 74 31 02 43 52 ...1tablet1t1.CR
| 4080: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 EATE TABLE t1(x)
| page 2 offset 4096
| 0: 0d 00 00 00 01 0f e2 00 0f e2 00 00 00 00 00 00 ................
| 4064: 00 00 1c 01 02 41 61 62 63 64 65 66 67 68 69 6a .....Aabcdefghij
| 4080: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqrstuvwxyz
| end abc.db
}]} {}
do_test 6.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
reset_db
breakpoint
do_test 6.2 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename abc.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 6e b8 0d 00 00 00 01 0f dc 00 0f dc 00 00 ..n.............
| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 22 01 06 17 ................
| 4064: 11 11 01 31 74 61 62 6c 65 74 31 74 31 02 43 52 ...1tablet1t1.CR
| 4080: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 EATE TABLE t1(x)
| page 2 offset 4096
| 0: 0d 00 00 00 01 0f e2 00 0f e2 00 00 00 00 00 00 ................
| 4064: 00 00 1c 01 02 8F FF FF FF 7E 65 66 67 68 69 6a .....Aabcdefghij
| 4080: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqrstuvwxyz
| end abc.db
}]} {}
do_test 6.3 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
reset_db
breakpoint
do_test 7.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 4108 pagesize 4096 filename x1.db
| page 1 offset 0
| 0: 02 01 00 00 00 00 14 15 40 00 00 00 00 00 00 00 ........@.......
| 16: 33 3a 6d 65 6d 6f 72 79 3a 02 02 02 02 02 02 02 3:memory:.......
| 32: 02 02 02 02 02 02 12 02 02 02 63 6f 6c 6f 72 20 ..........color
| 48: 73 70 61 63 00 f3 a0 81 a1 00 00 a0 02 02 02 02 spac............
| 64: 69 95 73 6f 36 00 ff 0d 00 97 8c 90 3f 0a 70 02 i.so6.......?.p.
| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 01 00 00 ................
| 96: 06 02 02 02 02 5f 02 02 02 2c 02 02 02 02 02 02 ....._...,......
| 112: 02 02 02 02 02 02 02 02 02 12 02 02 02 63 6f 6c .............col
| 128: 6f 72 20 73 70 61 63 00 f3 a0 81 a1 00 00 a0 02 or spac.........
| 144: 02 02 02 69 95 73 6f 36 00 ff 0d 00 97 8c 90 3f ...i.so6.......?
| 160: 0a 70 02 02 02 02 02 02 02 02 02 02 02 02 02 02 .p..............
| 176: 01 00 00 06 02 02 02 02 5f 02 02 02 2c 02 02 00 ........_...,...
| 192: 00 01 00 01 00 00 00 01 00 02 fe 00 00 03 00 01 ................
| 208: 00 00 00 01 c5 04 00 00 00 01 00 01 00 00 00 01 ................
| 224: 00 fa 02 00 00 00 03 00 01 00 00 00 81 00 04 00 ................
| 240: 00 00 01 00 01 00 00 00 01 00 02 00 fe 00 03 00 ................
| 256: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 272: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................
| 288: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 304: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 320: 01 00 02 00 00 00 03 00 01 00 00 00 40 00 84 00 ............@...
| 336: 84 00 84 00 01 00 00 00 09 00 06 00 f5 00 01 00 ................
| 352: 08 01 03 00 03 00 62 00 62 00 23 00 01 00 62 00 ......b.b.#...b.
| 368: 04 00 1e 00 62 00 62 00 62 00 01 00 00 00 0a 00 ....b.b.b.......
| 384: 01 00 03 00 01 00 03 00 04 00 02 00 01 00 01 00 ................
| 400: 08 00 01 00 31 c6 00 03 00 0c 00 12 00 18 00 02 ....1...........
| 416: 00 05 00 08 00 02 00 06 00 08 00 02 00 07 00 08 ................
| 432: 00 02 00 01 00 01 00 08 00 01 00 0c 00 03 00 16 ................
| 448: 00 1c 00 22 00 01 00 03 00 05 00 06 00 07 00 02 ................
| 464: 00 05 00 09 00 02 00 06 00 09 00 02 00 07 00 09 ................
| 480: 00 00 00 00 01 00 05 00 00 00 01 00 01 00 00 00 ................
| 496: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................
| 512: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 528: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 544: 01 00 02 00 00 f6 03 00 00 02 00 00 01 00 04 00 ................
| 560: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 576: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 592: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................
| 608: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 624: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 640: 01 3d 02 00 00 00 03 00 06 00 00 00 01 00 01 00 .=..............
| 656: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 672: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 688: 01 00 02 00 00 00 55 52 4c 52 65 71 75 65 73 74 ......URLRequest
| 704: 43 6f 6e 00 00 00 01 01 0e d4 00 04 00 00 00 01 Con.............
| 720: 0e f8 00 04 00 00 00 01 0f 1c 00 04 00 00 00 01 ................
| 736: 0f 00 00 01 00 00 00 01 0f 86 00 01 00 00 00 01 ................
| 752: 0f 84 00 01 00 00 00 01 00 00 01 0f c0 00 01 00 ................
| 768: 00 00 01 0f e8 00 d6 0f 00 01 6f 00 02 0f d6 00 ..........o.....
| 784: 02 34 03 03 03 00 01 00 00 00 01 00 05 00 00 00 .4..............
| 800: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................
| 816: 00 00 01 00 04 00 00 00 01 00 01 00 00 00 01 00 ................
| 832: 02 00 00 00 03 00 01 00 10 00 01 00 04 00 00 00 ................
| 848: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 00 02 ................
| 864: 00 00 01 40 04 00 00 03 01 00 01 00 00 00 01 00 ...@............
| 880: 02 00 00 00 03 00 01 00 00 00 00 00 01 0e f8 00 ................
| 896: 04 77 4f 46 32 73 40 23 70 00 00 00 70 00 1f 00 .wOF2s@#p...p...
| 912: 00 00 d8 00 00 00 ff ff 00 00 00 00 43 00 00 00 ............C...
| 928: 00 00 ff ff ff ff ff 00 00 a8 00 00 0c 00 00 00 ................
| 1024: 00 00 00 00 00 00 00 00 00 00 10 22 00 22 0f 00 ................
| 1040: 00 00 00 00 00 00 10 22 00 00 70 00 1f 00 00 0f ..........p.....
| 1056: d8 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00 ................
| 1072: 00 01 00 00 00 3f 23 70 00 00 00 01 0f 1c 00 04 .....?#p........
| 1088: 00 00 00 01 0f 40 00 01 00 00 00 01 0f 86 00 01 .....@..........
| 1104: 00 00 00 01 0f 84 00 01 00 00 00 01 00 00 01 0f ................
| 1120: c0 00 01 00 00 00 01 0f e8 00 01 0f d6 00 6f 00 ..............o.
| 1136: 02 0f d6 00 03 02 31 03 2b 03 2a f2 00 0f d4 00 ......1.+.*.....
| 1152: 01 00 08 00 01 00 04 03 2b 00 02 02 32 00 01 0f ........+...2...
| 1168: c8 01 15 00 02 20 c8 00 02 12 ad 02 00 24 06 c0 ..... .......$..
| 1184: 00 00 00 03 00 00 01 24 00 2a 06 e4 00 00 00 03 .......$.*......
| 1200: 00 00 01 25 00 38 07 0e 00 00 00 03 00 00 01 26 ...%.8.........&
| 1216: 00 34 07 46 00 00 00 03 00 00 01 27 00 1c 07 7a .4.F.......'...z
| 1232: 00 00 00 03 00 00 01 28 00 2a 07 96 00 00 00 03 .......(.*......
| 1248: 00 e5 01 29 00 34 07 c0 00 00 00 03 00 00 01 2a ...).4.........*
| 1264: 67 34 07 f4 00 00 00 03 00 00 01 2b 00 22 08 28 g4.........+...(
| 1280: 00 00 00 00 01 00 01 00 00 00 01 00 02 00 00 00 ................
| 1296: 03 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 ................
| 1312: 01 00 00 00 01 00 02 00 00 00 03 00 00 02 00 00 ................
| 1328: 01 00 04 00 00 00 01 00 01 00 00 00 01 00 02 00 ................
| 1344: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................
| 1360: 01 00 00 00 01 00 02 00 00 00 03 00 01 00 00 21 ...............!
| 1376: 04 00 01 00 00 00 00 00 01 00 00 00 01 00 02 00 ................
| 1392: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................
| 1408: 01 00 00 00 01 00 02 00 00 00 03 00 01 00 00 00 ................
| 1424: 01 00 05 00 00 00 01 00 01 00 00 01 00 02 02 02 ................
| 1440: 12 02 02 02 63 6f 6c 6f 72 20 73 70 61 63 00 f3 ....color spac..
| 1456: a0 81 a1 00 00 a0 02 02 02 02 69 95 73 6f 36 00 ..........i.so6.
| 1472: ff 0d 00 97 8c 90 3f 0a 70 02 02 02 02 02 02 02 ......?.p.......
| 1488: 02 02 02 02 02 02 02 01 00 00 06 02 02 02 02 5f ..............._
| 1504: 02 02 02 2c 02 02 00 00 01 00 01 00 00 00 01 00 ...,............
| 1520: 02 fe 00 00 03 00 01 00 00 00 01 c5 04 00 00 00 ................
| 1536: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................
| 1552: 00 00 81 00 04 00 00 00 01 00 01 00 00 00 01 00 ................
| 1568: 02 00 fe 00 03 00 01 00 00 00 01 00 04 00 00 00 ................
| 1584: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................
| 1600: 00 00 01 00 04 00 00 00 01 00 01 00 00 00 01 00 ................
| 1616: 02 00 00 00 03 00 01 00 00 00 01 00 04 00 00 00 ................
| 1632: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................
| 1648: 00 00 40 00 84 00 84 00 84 00 01 00 00 00 09 00 ..@.............
| 1664: 06 00 f5 00 01 00 08 01 03 15 15 15 15 15 15 15 ................
| 1680: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................
| 1696: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................
| 1712: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................
| 1728: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................
| 1744: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................
| 1760: 15 15 15 15 15 15 15 15 15 15 15 00 03 00 62 00 ..............b.
| 1776: 62 00 23 00 01 00 62 00 04 00 1e 00 62 00 62 00 b.#...b.....b.b.
| 1792: 62 00 01 00 00 00 0a 00 01 00 03 00 01 00 03 00 b...............
| 1808: 04 00 02 00 01 00 01 00 08 00 01 00 31 c6 00 03 ............1...
| 1824: 00 0c 00 12 00 18 00 02 00 05 00 08 00 02 00 06 ................
| 1840: 00 08 00 02 00 07 00 08 00 02 00 01 00 01 00 08 ................
| 1856: 00 01 00 0c 00 03 00 16 00 1c 00 22 00 01 00 03 ................
| 1872: 00 05 00 06 00 07 00 02 00 05 00 09 00 02 00 06 ................
| 1888: 00 09 00 02 00 07 00 09 00 00 00 00 01 00 05 00 ................
| 1904: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................
| 1920: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................
| 1936: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................
| 1952: 00 00 01 0f d6 00 02 34 03 03 03 00 01 00 00 00 .......4........
| 1968: 01 00 05 00 00 00 01 00 01 00 00 00 01 00 02 00 ................
| 1984: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................
| 2000: 01 00 00 00 01 00 02 fc 42 dc 19 5c 74 23 18 cd ........B...t#..
| 2016: b3 a5 a8 7a 90 40 1d 66 12 5d e5 4f 85 00 68 f4 ...z.@.f.].O..h.
| 2032: 05 98 86 25 24 dd bc c2 f6 f6 4e a3 e2 61 d2 c6 ...%$.....N..a..
| 2048: aa c1 56 50 d4 80 82 35 f1 e2 59 41 50 a6 da 51 ..VP...5..YAP..Q
| 2064: d4 62 9c 19 94 58 aa 31 30 8a 22 c2 5f 33 2b c9 .b...X.10..._3+.
| 2080: b6 e6 b4 11 4e 51 82 c4 d8 b6 d8 b4 06 04 fb 68 ....NQ.........h
| 2096: f4 d2 6f e7 cb 8a a8 82 d5 74 00 00 00 00 00 00 ..o......t......
| 2368: 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 ................
| 2432: 00 00 00 00 00 03 00 01 00 10 00 01 00 04 00 00 ................
| 2448: 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 00 ................
| 2464: 02 00 00 01 40 04 00 00 03 01 00 01 00 00 00 01 ....@...........
| 2480: 00 02 00 00 00 03 00 01 00 00 00 00 00 01 0e f8 ................
| 2496: 00 04 77 4f 46 32 73 40 23 70 00 00 00 70 00 1f ..wOF2s@#p...p..
| 2512: 00 00 00 d8 00 00 00 ff ff 00 00 00 00 43 00 00 .............C..
| 2528: 00 00 00 ff ff ff ff ff 00 00 a8 00 00 0c 00 00 ................
| 2624: 00 00 00 00 00 00 00 00 00 00 00 10 22 00 22 0f ................
| 2640: 00 00 00 00 00 00 00 10 22 00 00 70 00 1f 00 00 ...........p....
| 2656: 0f d8 00 00 00 00 00 00 00 00 00 03 00 00 00 00 ................
| 2672: 00 00 01 00 00 00 3f 23 70 00 00 00 01 0f 1c 00 ......?#p.......
| 2688: 04 00 00 00 01 0f 40 00 01 00 00 00 01 0f 86 00 ......@.........
| 2704: 01 00 00 00 01 0f 84 00 01 00 00 00 01 00 00 01 ................
| 2720: 0f c0 00 01 00 00 00 01 0f e8 00 01 0f d6 00 6f ...............o
| 2736: 00 02 0f d6 00 03 02 31 03 2b 03 2a f2 00 0f d4 .......1.+.*....
| 2752: 00 01 00 08 00 01 00 04 03 2b 00 02 02 32 00 01 .........+...2..
| 2768: 0f c8 01 15 00 02 20 c8 00 02 12 ad 02 00 24 06 ...... .......$.
| 2784: c0 00 00 5a 03 00 00 01 24 00 2a 06 e4 00 00 00 ...Z....$.*.....
| 2800: 03 00 00 01 25 00 38 07 0e 00 00 00 03 00 00 01 ....%.8.........
| 2816: 26 00 34 07 46 00 00 00 03 00 00 01 27 00 1c 07 &.4.F.......'...
| 2832: 7a 00 00 00 03 00 00 01 28 00 2a 07 96 00 00 00 z.......(.*.....
| 2848: 03 00 e5 01 29 00 34 07 c0 00 00 00 03 00 00 01 ....).4.........
| 2864: 2a 67 34 07 f4 00 00 00 03 00 00 01 2b 00 22 08 *g4.........+...
| 2880: 28 00 00 00 00 01 00 01 00 00 00 01 00 02 00 00 (...............
| 2896: 00 03 00 01 00 00 00 01 00 00 00 01 00 00 00 01 ................
| 2912: 00 01 00 00 00 01 00 02 00 00 00 03 00 00 02 00 ................
| 2928: 00 01 00 04 00 00 00 01 00 01 00 00 00 00 00 00 ................
| 2992: 00 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H..............
| 3504: 00 00 00 00 00 00 00 00 00 00 00 97 00 00 00 00 ................
| 3904: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 ................
| 3920: 03 fe 00 00 01 36 00 3c 0a 38 00 00 00 03 00 00 .....6.<.8......
| 3936: 01 37 00 20 0a 74 00 00 00 fb ff ff 00 38 00 2a .7. .t.......8.*
| 3952: 0a 94 00 00 00 03 00 00 01 39 4f 54 54 4f 00 0e .........9OTTO..
| 3968: 00 80 00 03 00 60 43 46 46 20 e3 ae 89 2a 00 00 .....`CFF ...*..
| 3984: 02 b0 00 00 02 76 42 50 4f 53 00 15 00 0a 00 00 .....vBPOS......
| 4000: 05 28 00 00 00 0c 54 53 55 42 c9 70 c3 06 00 00 .(....TSUB.p....
| 4016: 05 34 1f 00 40 00 48 00 00 00 00 00 00 00 00 00 .4..@.H.........
| 4064: 00 00 00 00 00 08 00 01 00 01 00 01 00 01 00 06 ................
| 4080: 00 02 00 08 00 01 00 01 00 01 00 01 00 00 00 00 ................
| end x1.db
}]} {}
do_test 7.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {1 {file is not a database}}
reset_db
do_test 8.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename db.sqlite
| page 1 offset 0
| 0: ac ae b3 76 74 65 20 66 6f 72 6d 61 74 20 33 00 ...vte format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
| 96: 00 2e 76 8a 0d ff ff ff 1e 0f cb 00 0f cb 00 00 ..v.............
| 4032: 00 00 00 00 00 00 00 00 00 00 00 33 01 06 17 19 ...........3....
| 4048: 19 01 43 74 61 62 6c 65 54 61 62 6c 65 30 54 61 ..CtableTable0Ta
| 4064: 62 6c 65 30 02 43 52 45 41 54 45 20 54 41 42 4c ble0.CREATE TABL
| 4080: 45 20 54 61 62 6c 65 30 20 28 43 6f 6c 30 20 29 E Table0 (Col0 )
| page 2 offset 4096
| 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................
| end db.sqlite
}]} {}
do_test 8.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
reset_db
do_test 9.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 16384 pagesize 4096t 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 ........
| 32: 00 00 00 0r 00 00 00 00 00 00 00 06 00 00 00 04 ..
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ........
| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a .......j
| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .
| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..tablet
| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6econ
| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45
| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 )
| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WOWID^..
| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 6tt_d
| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a z
| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.ABLE '
| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20id
| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20
| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEYB)]..
| 3744: 17 23 23 01 81 B1 74 61 62 6c 65 74 74 74 5f 63 _c
| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e o_conten
| 3776: 7 04 01 03 00 011 54 45 20 54 41 42 4c 45 20 27 t.CRLE '
| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20
| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INIMARY
| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 7EY(s
| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 T
| 3936: 48 4f 55 54 20 52 4f 57 49 4 58 58 02 07 17 1d 1d ..
| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 .tt_data
| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 2ATE
| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 '
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (iR PRIM
| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42k B
| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c
| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettTE VI
| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 t
| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 U5(a, b)
| page 4 offset 12288
| 0: 0a 00 00 00 03 0f ea 00 0f fa 0f f2 0f ea 00 00 ........
| 4064: 00 00 00 00 00 00 00 00 00 00 07 04 01 01 01 05 ..
| 4080: 06 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02 ........
| end ro2.t
}]} {}
do_test 9.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
finish_test
+549
View File
@@ -0,0 +1,549 @@
# 2024 May 1
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt3
#| 0: d5 d5 9b d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 d5 ................
#| 16: 04 00 00 00 1d 00 00 00 00 00 00 00 5f 5f 5f 5f ............____
#| 32: 5f 5f 5f 5f 5f 5f 5f 5f 71 5f 5f 5f 02 02 02 02 ________q___....
#| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
#| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
#| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
#| 96: 02 02 02 02
#-------------------------------------------------------------------------
reset_db
do_test 1.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 3821 pagesize 1024 filename clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
| 96: 00 2e 7a 70 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 a0 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 29 29 ..............))
| 464: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 480: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 496: 29 29 29 dd dd dd dd dd dd dd dd dd dd dd dd dd ))).............
| 512: dd dd dd dd dd dd dd dd dd 6e 69 d2 e9 e9 e9 d2 .........ni.....
| 528: d2 d2 d2 d2 dd dd dd dd dd dd dd dd dd dd dd dd ................
| 544: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 560: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 576: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 592: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 608: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 624: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 640: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 656: dd dd dd dd dd dd dd da dd dd dd dd dd dd dd dd ................
| 672: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 688: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 704: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 720: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 736: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 752: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 768: dd dd dd dd dd dd dd dd dd dd dd dd dd 29 29 29 .............)))
| 784: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 800: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 816: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 832: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 848: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 864: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 880: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 896: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 912: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 928: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 944: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 960: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 976: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 992: 29 29 29 29 29 29 29 29 29 29 dd dd dd dd dd dd ))))))))))......
| 1008: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| page 2 offset 1024
| 0: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 16: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 32: dd dd 6e 69 d2 e9 e9 e9 d2 d2 d2 d2 d2 dd dd dd ..ni............
| 48: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 64: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 80: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 96: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 112: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 128: dd dd dd dd dd dd 29 29 29 29 29 29 29 29 29 29 ......))))))))))
| 144: 29 29 29 29 29 29 29 29 29 ad a5 29 29 29 29 00 )))))))))..)))).
| 160: 75 9c 11 00 5b e5 64 28 7c ca 09 69 28 2d 69 00 u...[.d(|..i(-i.
| 176: 85 88 6c 81 48 83 a0 93 c0 c0 82 8b 81 84 85 f9 ..l.H...........
| 192: 88 7a 00 7f 00 96 40 7b 12 4b 84 75 a0 00 99 a0 .z....@..K.u....
| 208: df a0 7e 81 c6 90 8f 7f 84 85 cc 84 82 90 88 60 ..~............`
| 224: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 240: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 256: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 272: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 288: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 832: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 848: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 864: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 880: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 896: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 912: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 928: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 944: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 960: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| page 3 offset 2048
| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 832: 02 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 848: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 864: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 880: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 896: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 912: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 928: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 944: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 960: 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| page 4 offset 3072
| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 5f 5f 5f 5f 5f 5f 5f 00 d5 fe fe fe 08 00 00 00 _______.........
| end clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056
}]} {}
sqlite3_dbdata_init db
do_execsql_test 1.1 {
PRAGMA writable_schema = 1;
}
do_test 1.2 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
#-------------------------------------------------------------------------
reset_db
do_test 2.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 3821 pagesize 1024 filename clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 04 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
| 96: 00 2e 7a 70 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 a0 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 29 29 ..............))
| 464: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 480: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 496: 29 29 29 dd dd dd dd dd dd dd dd dd dd dd dd dd ))).............
| 512: dd dd dd dd dd dd dd dd dd 6e 69 d2 e9 e9 e9 d2 .........ni.....
| 528: d2 d2 d2 d2 dd dd dd dd dd dd dd dd dd dd dd dd ................
| 544: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 560: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 576: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 592: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 608: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 624: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 640: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 656: dd dd dd dd dd dd dd da dd dd dd dd dd dd dd dd ................
| 672: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 688: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 704: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 720: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 736: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 752: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 768: dd dd dd dd dd dd dd dd dd dd dd dd dd 29 29 29 .............)))
| 784: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 800: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 816: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 832: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 848: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 864: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 880: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 896: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 912: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 928: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 944: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 960: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 976: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
| 992: 29 29 29 29 29 29 29 29 29 29 dd dd dd dd dd dd ))))))))))......
| 1008: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| page 2 offset 1024
| 0: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 16: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 32: dd dd 6e 69 d2 e9 e9 e9 d2 d2 d2 d2 d2 dd dd dd ..ni............
| 48: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 64: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 80: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 96: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 112: dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd ................
| 128: dd dd dd dd dd dd 29 29 29 29 29 29 29 29 29 29 ......))))))))))
| 144: 29 29 29 29 29 29 29 29 29 ad a5 29 29 29 29 00 )))))))))..)))).
| 160: 75 9c 11 00 5b e5 64 28 7c ca 09 69 28 2d 69 00 u...[.d(|..i(-i.
| 176: 85 88 6c 81 48 83 a0 93 c0 c0 82 8b 81 84 85 f9 ..l.H...........
| 192: 88 7a 00 7f 00 96 40 7b 12 4b 84 75 a0 00 99 a0 .z....@..K.u....
| 208: df a0 7e 81 c6 90 8f 7f 84 85 cc 84 82 90 88 60 ..~............`
| 224: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 240: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 256: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 272: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 288: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 832: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 848: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 864: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 880: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 896: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 912: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 928: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 944: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 960: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| page 3 offset 2048
| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 752: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 768: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 784: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 800: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 816: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 832: 02 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 848: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 864: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 880: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 896: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 912: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 928: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 944: 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ................
| 960: 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 976: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 992: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 1008: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| page 4 offset 3072
| 0: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 16: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 32: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 48: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 64: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 96: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 112: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 128: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 144: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 160: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 176: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 192: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 208: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 224: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 240: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 256: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 272: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 288: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 304: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 320: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 336: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 352: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 368: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 384: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 400: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 416: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 432: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 448: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 464: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 480: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 496: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 512: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 528: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 544: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 560: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 576: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 592: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 608: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 624: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 640: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 656: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 672: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 688: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 704: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 720: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ................
| 736: 5f 5f 5f 5f 5f 5f 5f 00 d5 fe fe fe 08 00 00 00 _______.........
| end clusterfuzz-testcase-sql_recovery_fuzzer-5803962339885056
}]} {}
sqlite3_dbdata_init db
do_execsql_test 2.1 {
PRAGMA writable_schema = 1;
}
do_test 2.2 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
finish_test
+63
View File
@@ -0,0 +1,63 @@
# 2024 May 15
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt4
database_may_be_corrupt
if {[permutation]!="inmemory_journal"} {
# This test cannot be run with the inmemory_journal permutation, as it
# must open a truncated, corrupt, database file. With the inmemory_journal
# permutation, this fails (SQLITE_CORRUPT error) when the [sqlite3] wrapper
# executes "PRAGMA journal_mode = memory".
do_execsql_test 1.0 {
CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL, filler BLOB NOT NULL DEFAULT 13);
-- CREATE UNIQUE INDEX rows_index ON rows(indexed);
INSERT INTO rows(indexed, unindexed, filler) VALUES(1, 1, x'31');
INSERT INTO rows(indexed, unindexed, filler) VALUES(2, 2, x'32');
INSERT INTO rows(indexed, unindexed, filler) VALUES(4, 4, x'34');
INSERT INTO rows(indexed, unindexed, filler) VALUES(8, 8, randomblob(2048));
}
db close
do_test 1.1 {
set sz [expr [file size test.db] - 1024]
set fd [open test.db]
fconfigure $fd -translation binary
set data [read $fd $sz]
set fd2 [open test.db2 w]
fconfigure $fd2 -translation binary
puts -nonewline $fd2 $data
close $fd2
set {} {}
} {}
do_test 1.2 {
forcedelete test.db3
sqlite3 db test.db2
set R [sqlite3_recover_init db main test.db3]
$R run
$R finish
} {}
do_test 1.3 {
sqlite3 db test.db3
execsql {
SELECT indexed, unindexed FROM rows
}
} {1 1 2 2 4 4 8 8}
}
finish_test
+84
View File
@@ -0,0 +1,84 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverfault
#--------------------------------------------------------------------------
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
#--------------------------------------------------------------------------
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(1000)), randomblob(2000));
CREATE INDEX i1 ON t1(b, c);
ANALYZE;
}
faultsim_save_and_close
do_faultsim_test 1 -faults oom* -prep {
catch { db2 close }
faultsim_restore_and_reopen
} -body {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 test.db2
compare_dbs db db2
db2 close
}
}
faultsim_restore_and_reopen
do_execsql_test 2.0 {
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(1000)), hex(randomblob(2000)));
PRAGMA writable_schema = 1;
DELETE FROM sqlite_schema WHERE name='t2';
}
faultsim_save_and_close
do_faultsim_test 2 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
}
finish_test
+102
View File
@@ -0,0 +1,102 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverfault2
#--------------------------------------------------------------------------
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
#--------------------------------------------------------------------------
do_execsql_test 1.0 "
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(2, '\012hello\015world\012today\n');
"
faultsim_save_and_close
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_faultsim_test 1 -faults oom* -prep {
catch { db2 close }
faultsim_restore_and_reopen
set ::lSql [list]
} -body {
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 ""
db2 eval [join $::lSql ";"]
compare_dbs db db2
db2 close
}
}
ifcapable utf16 {
reset_db
do_execsql_test 2.0 "
PRAGMA encoding='utf-16';
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(2, '\012hello\015world\012today\n');
"
faultsim_save_and_close
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_faultsim_test 2 -faults oom-t* -prep {
catch { db2 close }
faultsim_restore_and_reopen
set ::lSql [list]
} -body {
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 ""
db2 eval [join $::lSql ";"]
compare_dbs db db2
db2 close
}
}
}
finish_test
+189
View File
@@ -0,0 +1,189 @@
# 2019 April 23
#
# 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.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverold
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "sql: $sql"
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
proc do_recover_test {tn {tsql {}} {res {}}} {
forcedelete test.db2
forcedelete rstate.db
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
$R finish
sqlite3 db2 test.db2
if {$tsql==""} {
uplevel [list do_test $tn.1 [list compare_dbs db db2] {}]
} else {
uplevel [list do_execsql_test -db db2 $tn.1 $tsql $res]
}
db2 close
forcedelete test.db2
forcedelete rstate.db
set ::sqlhook [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config lostandfound lost_and_found
$R run
$R finish
sqlite3 db2 test.db2
db2 eval [join $::sqlhook ";"]
db cache flush
if {$tsql==""} {
compare_dbs db db2
uplevel [list do_test $tn.sql [list compare_dbs db db2] {}]
} else {
uplevel [list do_execsql_test -db db2 $tn.sql $tsql $res]
}
db2 close
}
proc my_sql_hook {sql} {
lappend ::sqlhook $sql
return 0
}
set doc {
hello
world
}
do_execsql_test 1.1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 4, X'1234567800');
INSERT INTO t1 VALUES(2, 'test', 8.1);
INSERT INTO t1 VALUES(3, $doc, 8.4);
}
do_recover_test 1.1.2
do_execsql_test 1.2.1 "
DELETE FROM t1;
INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13);
"
do_recover_test 1.2.2
do_execsql_test 1.3.1 "
CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t2 VALUES(NULL, 1, 2);
INSERT INTO t2 VALUES(NULL, 3, 4);
INSERT INTO t2 VALUES(NULL, 5, 6);
CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t3 VALUES(NULL, 1, 2);
INSERT INTO t3 VALUES(NULL, 3, 4);
INSERT INTO t3 VALUES(NULL, 5, 6);
DELETE FROM t2;
"
do_recover_test 1.3.2
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1.0 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_recover_test 2.1.1
do_execsql_test 2.2.0 {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE name='t1';
}
do_recover_test 2.2.1 {
SELECT name FROM sqlite_master
} {lost_and_found}
do_execsql_test 2.3.0 {
CREATE TABLE lost_and_found(a, b, c);
}
do_recover_test 2.3.1 {
SELECT name FROM sqlite_master
} {lost_and_found lost_and_found_0}
do_execsql_test 2.4.0 {
CREATE TABLE lost_and_found_0(a, b, c);
}
do_recover_test 2.4.1 {
SELECT name FROM sqlite_master;
SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
2 2 3 {} 2 3 1
2 2 3 {} 5 6 4
2 2 3 {} 8 9 7
}
do_execsql_test 2.5 {
CREATE TABLE x1(a, b, c);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
)
INSERT INTO x1 SELECT i, i, hex(randomblob(500)) FROM s;
DROP TABLE x1;
}
do_recover_test 2.5.1 {
SELECT name FROM sqlite_master;
SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
2 2 3 {} 2 3 1
2 2 3 {} 5 6 4
2 2 3 {} 8 9 7
}
ifcapable !secure_delete {
do_test 2.6 {
forcedelete test.db2
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R config freelistcorrupt 1
$R run
$R finish
sqlite3 db2 test.db2
execsql { SELECT count(*) FROM lost_and_found_1; } db2
} {103}
db2 close
}
#-------------------------------------------------------------------------
breakpoint
reset_db
do_recover_test 3.0
finish_test
+97
View File
@@ -0,0 +1,97 @@
# 2022 October 14
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
db close
sqlite3_test_control_pending_byte 0x1000000
set testprefix recoverpgsz
foreach {pgsz bOverflow} {
512 0 1024 0 2048 0 4096 0 8192 0 16384 0 32768 0 65536 0
512 1 1024 1 2048 1 4096 1 8192 1 16384 1 32768 1 65536 1
} {
reset_db
execsql "PRAGMA page_size = $pgsz"
execsql "PRAGMA auto_vacuum = 0"
do_execsql_test 1.$pgsz.$bOverflow.1 {
CREATE TABLE t1(a, b, c);
CREATE INDEX i1 ON t1(b, a, c);
INSERT INTO t1(a, b) VALUES(1, 2), (3, 4), (5, 6);
DELETE FROM t1 WHERE a=3;
}
if {$bOverflow} {
do_execsql_test 1.$pgsz.$bOverflow.1a {
UPDATE t1 SET c = randomblob(100000);
}
}
db close
set fd [open test.db]
fconfigure $fd -translation binary
seek $fd $pgsz
set pg1 [read $fd $pgsz]
set pg2 [read $fd $pgsz]
close $fd
set fd2 [open test.db2 w]
fconfigure $fd2 -translation binary
seek $fd2 $pgsz
puts -nonewline $fd2 $pg1
close $fd2
sqlite3 db2 test.db2
do_test 1.$pgsz.$bOverflow.2 {
set R [sqlite3_recover_init db2 main test.db3]
$R run
$R finish
} {}
sqlite3 db3 test.db3
do_test 1.$pgsz.$bOverflow.3 {
db3 eval { SELECT * FROM sqlite_schema }
db3 eval { PRAGMA page_size }
} $pgsz
db2 close
db3 close
forcedelete test.db3
forcedelete test.db2
set fd2 [open test.db2 w]
fconfigure $fd2 -translation binary
seek $fd2 $pgsz
puts -nonewline $fd2 $pg2
close $fd2
sqlite3 db2 test.db2
do_test 1.$pgsz.$bOverflow.4 {
set R [sqlite3_recover_init db2 main test.db3]
$R run
$R finish
} {}
sqlite3 db3 test.db3
do_test 1.$pgsz.$bOverflow.5 {
db3 eval { SELECT * FROM sqlite_schema }
db3 eval { PRAGMA page_size }
} $pgsz
db2 close
db3 close
}
finish_test
+50
View File
@@ -0,0 +1,50 @@
# 2022 September 07
#
# 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.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_ROWIDS option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverrowid
proc recover {db bRowids output} {
forcedelete $output
set R [sqlite3_recover_init db main test.db2]
$R config rowids $bRowids
$R run
$R finish
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
DELETE FROM t1 WHERE a IN (1, 3);
}
do_test 1.1 {
recover db 0 test.db2
sqlite3 db2 test.db2
execsql { SELECT rowid, a, b FROM t1 ORDER BY rowid} db2
} {1 2 2 2 4 4}
do_test 1.2 {
db2 close
recover db 1 test.db2
sqlite3 db2 test.db2
execsql { SELECT rowid, a, b FROM t1 ORDER BY rowid} db2
} {2 2 2 4 4 4}
db2 close
finish_test
+89
View File
@@ -0,0 +1,89 @@
# 2022 September 25
#
# 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.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_SLOWINDEXES option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverslowidx
do_execsql_test 1.0 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
}
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_test 1.1 {
set lSql [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
while {[$R step]==0} { }
$R finish
} {}
do_test 1.2 {
set lSql
} [list {*}{
{BEGIN}
{PRAGMA writable_schema = on}
{PRAGMA foreign_keys = off}
{PRAGMA encoding = 'UTF-8'}
{PRAGMA page_size = '1024'}
{PRAGMA auto_vacuum = '0'}
{PRAGMA user_version = '0'}
{PRAGMA application_id = '0'}
{CREATE TABLE t1(a, b)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (1, 1, 1)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (2, 2, 2)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (3, 3, 3)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (4, 4, 4)}
{CREATE INDEX i1 ON t1(a)}
{PRAGMA writable_schema = off}
{COMMIT}
}]
do_test 1.3 {
set lSql [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config slowindexes 1
while {[$R step]==0} { }
$R finish
} {}
do_test 1.4 {
set lSql
} [list {*}{
{BEGIN}
{PRAGMA writable_schema = on}
{PRAGMA foreign_keys = off}
{PRAGMA encoding = 'UTF-8'}
{PRAGMA page_size = '1024'}
{PRAGMA auto_vacuum = '0'}
{PRAGMA user_version = '0'}
{PRAGMA application_id = '0'}
{CREATE TABLE t1(a, b)}
{CREATE INDEX i1 ON t1(a)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (1, 1, 1)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (2, 2, 2)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (3, 3, 3)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (4, 4, 4)}
{PRAGMA writable_schema = off}
{COMMIT}
}]
finish_test
+52
View File
@@ -0,0 +1,52 @@
# 2022 September 13
#
# 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.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoversql
do_execsql_test 1.0 {
CREATE TABLE "x.1" (x, y);
INSERT INTO "x.1" VALUES(1, 1), (2, 2), (3, 3);
CREATE INDEX "i.1" ON "x.1"(y, x);
}
proc sql_hook {sql} {
incr ::iSqlHook
if {$::iSqlHook==$::sql_hook_cnt} { return 4 }
return 0
}
do_test 1.1 {
set ::sql_hook_cnt -1
set ::iSqlHook 0
set R [sqlite3_recover_init_sql db main sql_hook]
$R run
$R finish
} {}
set nSqlCall $iSqlHook
for {set ii 1} {$ii<$nSqlCall} {incr ii} {
set iSqlHook 0
set sql_hook_cnt $ii
do_test 1.$ii.a {
set R [sqlite3_recover_init_sql db main sql_hook]
$R run
} {1}
do_test 1.$ii.b {
list [catch { $R finish } msg] $msg
} {1 {callback returned an error - 4}}
}
finish_test
File diff suppressed because it is too large. Load diff
+249
View File
@@ -0,0 +1,249 @@
/*
** 2022-08-27
**
** 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.
**
*************************************************************************
**
** This file contains the public interface to the "recover" extension -
** an SQLite extension designed to recover data from corrupted database
** files.
*/
/*
** OVERVIEW:
**
** To use the API to recover data from a corrupted database, an
** application:
**
** 1) Creates an sqlite3_recover handle by calling either
** sqlite3_recover_init() or sqlite3_recover_init_sql().
**
** 2) Configures the new handle using one or more calls to
** sqlite3_recover_config().
**
** 3) Executes the recovery by repeatedly calling sqlite3_recover_step() on
** the handle until it returns something other than SQLITE_OK. If it
** returns SQLITE_DONE, then the recovery operation completed without
** error. If it returns some other non-SQLITE_OK value, then an error
** has occurred.
**
** 4) Retrieves any error code and English language error message using the
** sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs,
** respectively.
**
** 5) Destroys the sqlite3_recover handle and frees all resources
** using sqlite3_recover_finish().
**
** The application may abandon the recovery operation at any point
** before it is finished by passing the sqlite3_recover handle to
** sqlite3_recover_finish(). This is not an error, but the final state
** of the output database, or the results of running the partial script
** delivered to the SQL callback, are undefined.
*/
#ifndef _SQLITE_RECOVER_H
#define _SQLITE_RECOVER_H
#include "sqlite3.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
** An instance of the sqlite3_recover object represents a recovery
** operation in progress.
**
** Constructors:
**
** sqlite3_recover_init()
** sqlite3_recover_init_sql()
**
** Destructor:
**
** sqlite3_recover_finish()
**
** Methods:
**
** sqlite3_recover_config()
** sqlite3_recover_errcode()
** sqlite3_recover_errmsg()
** sqlite3_recover_run()
** sqlite3_recover_step()
*/
typedef struct sqlite3_recover sqlite3_recover;
/*
** These two APIs attempt to create and return a new sqlite3_recover object.
** In both cases the first two arguments identify the (possibly
** corrupt) database to recover data from. The first argument is an open
** database handle and the second the name of a database attached to that
** handle (i.e. "main", "temp" or the name of an attached database).
**
** If sqlite3_recover_init() is used to create the new sqlite3_recover
** handle, then data is recovered into a new database, identified by
** string parameter zUri. zUri may be an absolute or relative file path,
** or may be an SQLite URI. If the identified database file already exists,
** it is overwritten.
**
** If sqlite3_recover_init_sql() is invoked, then any recovered data will
** be returned to the user as a series of SQL statements. Executing these
** SQL statements results in the same database as would have been created
** had sqlite3_recover_init() been used. For each SQL statement in the
** output, the callback function passed as the third argument (xSql) is
** invoked once. The first parameter is a passed a copy of the fourth argument
** to this function (pCtx) as its first parameter, and a pointer to a
** nul-terminated buffer containing the SQL statement formated as UTF-8 as
** the second. If the xSql callback returns any value other than SQLITE_OK,
** then processing is immediately abandoned and the value returned used as
** the recover handle error code (see below).
**
** If an out-of-memory error occurs, NULL may be returned instead of
** a valid handle. In all other cases, it is the responsibility of the
** application to avoid resource leaks by ensuring that
** sqlite3_recover_finish() is called on all allocated handles.
*/
sqlite3_recover *sqlite3_recover_init(
sqlite3* db,
const char *zDb,
const char *zUri
);
sqlite3_recover *sqlite3_recover_init_sql(
sqlite3* db,
const char *zDb,
int (*xSql)(void*, const char*),
void *pCtx
);
/*
** Configure an sqlite3_recover object that has just been created using
** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function
** may only be called before the first call to sqlite3_recover_step()
** or sqlite3_recover_run() on the object.
**
** The second argument passed to this function must be one of the
** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument
** depend on the specific SQLITE_RECOVER_* symbol in use.
**
** SQLITE_OK is returned if the configuration operation was successful,
** or an SQLite error code otherwise.
*/
int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
/*
** SQLITE_RECOVER_LOST_AND_FOUND:
** The pArg argument points to a string buffer containing the name
** of a "lost-and-found" table in the output database, or NULL. If
** the argument is non-NULL and the database contains seemingly
** valid pages that cannot be associated with any table in the
** recovered part of the schema, data is extracted from these
** pages to add to the lost-and-found table.
**
** SQLITE_RECOVER_FREELIST_CORRUPT:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is set
** (argument is 1) and a lost-and-found table has been configured using
** SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is
** corrupt and an attempt is made to recover records from pages that
** appear to be linked into the freelist. Otherwise, pages on the freelist
** are ignored. Setting this option can recover more data from the
** database, but often ends up "recovering" deleted records. The default
** value is 0 (clear).
**
** SQLITE_RECOVER_ROWIDS:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is set
** (argument is 1), then an attempt is made to recover rowid values
** that are not also INTEGER PRIMARY KEY values. If this option is
** clear, then new rowids are assigned to all recovered rows. The
** default value is 1 (set).
**
** SQLITE_RECOVER_SLOWINDEXES:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is clear
** (argument is 0), then when creating an output database, the recover
** module creates and populates non-UNIQUE indexes right at the end of the
** recovery operation - after all recoverable data has been inserted
** into the new database. This is faster overall, but means that the
** final call to sqlite3_recover_step() for a recovery operation may
** be need to create a large number of indexes, which may be very slow.
**
** Or, if this option is set (argument is 1), then non-UNIQUE indexes
** are created in the output database before it is populated with
** recovered data. This is slower overall, but avoids the slow call
** to sqlite3_recover_step() at the end of the recovery operation.
**
** The default option value is 0.
*/
#define SQLITE_RECOVER_LOST_AND_FOUND 1
#define SQLITE_RECOVER_FREELIST_CORRUPT 2
#define SQLITE_RECOVER_ROWIDS 3
#define SQLITE_RECOVER_SLOWINDEXES 4
/*
** Perform a unit of work towards the recovery operation. This function
** must normally be called multiple times to complete database recovery.
**
** If no error occurs but the recovery operation is not completed, this
** function returns SQLITE_OK. If recovery has been completed successfully
** then SQLITE_DONE is returned. If an error has occurred, then an SQLite
** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not
** considered an error if some or all of the data cannot be recovered
** due to database corruption.
**
** Once sqlite3_recover_step() has returned a value other than SQLITE_OK,
** all further such calls on the same recover handle are no-ops that return
** the same non-SQLITE_OK value.
*/
int sqlite3_recover_step(sqlite3_recover*);
/*
** Run the recovery operation to completion. Return SQLITE_OK if successful,
** or an SQLite error code otherwise. Calling this function is the same
** as executing:
**
** while( SQLITE_OK==sqlite3_recover_step(p) );
** return sqlite3_recover_errcode(p);
*/
int sqlite3_recover_run(sqlite3_recover*);
/*
** If an error has been encountered during a prior call to
** sqlite3_recover_step(), then this function attempts to return a
** pointer to a buffer containing an English language explanation of
** the error. If no error message is available, or if an out-of memory
** error occurs while attempting to allocate a buffer in which to format
** the error message, NULL is returned.
**
** The returned buffer remains valid until the sqlite3_recover handle is
** destroyed using sqlite3_recover_finish().
*/
const char *sqlite3_recover_errmsg(sqlite3_recover*);
/*
** If this function is called on an sqlite3_recover handle after
** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK.
*/
int sqlite3_recover_errcode(sqlite3_recover*);
/*
** Clean up a recovery object created by a call to sqlite3_recover_init().
** The results of using a recovery object with any API after it has been
** passed to this function are undefined.
**
** This function returns the same value as sqlite3_recover_errcode().
*/
int sqlite3_recover_finish(sqlite3_recover*);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* ifndef _SQLITE_RECOVER_H */
+309
View File
@@ -0,0 +1,309 @@
/*
** 2022-08-27
**
** 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.
**
*************************************************************************
**
*/
#include "sqlite3recover.h"
#include "sqliteInt.h"
#include "tclsqlite.h"
#include <assert.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
typedef struct TestRecover TestRecover;
struct TestRecover {
sqlite3_recover *p;
Tcl_Interp *interp;
Tcl_Obj *pScript;
};
static int xSqlCallback(void *pSqlArg, const char *zSql){
TestRecover *p = (TestRecover*)pSqlArg;
Tcl_Obj *pEval = 0;
int res = 0;
pEval = Tcl_DuplicateObj(p->pScript);
Tcl_IncrRefCount(pEval);
res = Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj(zSql, -1));
if( res==TCL_OK ){
res = Tcl_EvalObjEx(p->interp, pEval, 0);
}
Tcl_DecrRefCount(pEval);
if( res ){
Tcl_BackgroundError(p->interp);
return TCL_ERROR;
}else{
Tcl_Obj *pObj = Tcl_GetObjResult(p->interp);
if( Tcl_GetCharLength(pObj)==0 ){
res = 0;
}else if( Tcl_GetIntFromObj(p->interp, pObj, &res) ){
Tcl_BackgroundError(p->interp);
return TCL_ERROR;
}
}
return res;
}
static int getDbPointer(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
Tcl_CmdInfo info;
if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), NULL);
return TCL_ERROR;
}
*pDb = *(sqlite3 **)info.objClientData;
return TCL_OK;
}
/*
** Implementation of the command created by [sqlite3_recover_init]:
**
** $cmd config OP ARG
** $cmd run
** $cmd errmsg
** $cmd errcode
** $cmd finalize
*/
static int testRecoverCmd(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
static struct RecoverSub {
const char *zSub;
int nArg;
const char *zMsg;
} aSub[] = {
{ "config", 2, "ARG" }, /* 0 */
{ "run", 0, "" }, /* 1 */
{ "errmsg", 0, "" }, /* 2 */
{ "errcode", 0, "" }, /* 3 */
{ "finish", 0, "" }, /* 4 */
{ "step", 0, "" }, /* 5 */
{ 0 }
};
int rc = TCL_OK;
int iSub = 0;
TestRecover *pTest = (TestRecover*)clientData;
if( objc<2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
return TCL_ERROR;
}
rc = Tcl_GetIndexFromObjStruct(interp,
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
);
if( rc!=TCL_OK ) return rc;
if( (objc-2)!=aSub[iSub].nArg ){
Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg);
return TCL_ERROR;
}
switch( iSub ){
case 0: assert( sqlite3_stricmp("config", aSub[iSub].zSub)==0 ); {
const char *aOp[] = {
"testdb", /* 0 */
"lostandfound", /* 1 */
"freelistcorrupt", /* 2 */
"rowids", /* 3 */
"slowindexes", /* 4 */
"invalid", /* 5 */
0
};
int iOp = 0;
int res = 0;
if( Tcl_GetIndexFromObj(interp, objv[2], aOp, "option", 0, &iOp) ){
return TCL_ERROR;
}
switch( iOp ){
case 0:
res = sqlite3_recover_config(pTest->p,
789, (void*)Tcl_GetString(objv[3]) /* MAGIC NUMBER! */
);
break;
case 1: {
const char *zStr = Tcl_GetString(objv[3]);
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_LOST_AND_FOUND, (void*)(zStr[0] ? zStr : 0)
);
break;
}
case 2: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_FREELIST_CORRUPT, (void*)&iVal
);
break;
}
case 3: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_ROWIDS, (void*)&iVal
);
break;
}
case 4: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_SLOWINDEXES, (void*)&iVal
);
break;
}
case 5: {
res = sqlite3_recover_config(pTest->p, 12345, 0);
break;
}
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
case 1: assert( sqlite3_stricmp("run", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_run(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
case 2: assert( sqlite3_stricmp("errmsg", aSub[iSub].zSub)==0 ); {
const char *zErr = sqlite3_recover_errmsg(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
break;
}
case 3: assert( sqlite3_stricmp("errcode", aSub[iSub].zSub)==0 ); {
int errCode = sqlite3_recover_errcode(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(errCode));
break;
}
case 4: assert( sqlite3_stricmp("finish", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_errcode(pTest->p);
int res2;
if( res!=SQLITE_OK ){
const char *zErr = sqlite3_recover_errmsg(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
}
res2 = sqlite3_recover_finish(pTest->p);
assert( res2==res );
if( res ) return TCL_ERROR;
break;
}
case 5: assert( sqlite3_stricmp("step", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_step(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
}
return TCL_OK;
}
/*
** sqlite3_recover_init DB DBNAME URI
*/
static int test_sqlite3_recover_init(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
static int iTestRecoverCmd = 1;
TestRecover *pNew = 0;
sqlite3 *db = 0;
const char *zDb = 0;
const char *zUri = 0;
char zCmd[128];
int bSql = clientData ? 1 : 0;
if( objc!=4 ){
const char *zErr = (bSql ? "DB DBNAME SCRIPT" : "DB DBNAME URI");
Tcl_WrongNumArgs(interp, 1, objv, zErr);
return TCL_ERROR;
}
if( getDbPointer(interp, objv[1], &db) ) return TCL_ERROR;
zDb = Tcl_GetString(objv[2]);
if( zDb[0]=='\0' ) zDb = 0;
pNew = (TestRecover*)ckalloc(sizeof(TestRecover));
if( bSql==0 ){
zUri = Tcl_GetString(objv[3]);
pNew->p = sqlite3_recover_init(db, zDb, zUri);
}else{
pNew->interp = interp;
pNew->pScript = objv[3];
Tcl_IncrRefCount(pNew->pScript);
pNew->p = sqlite3_recover_init_sql(db, zDb, xSqlCallback, (void*)pNew);
}
sprintf(zCmd, "sqlite_recover%d", iTestRecoverCmd++);
Tcl_CreateObjCommand(interp, zCmd, testRecoverCmd, (void*)pNew, 0);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zCmd, -1));
return TCL_OK;
}
/*
** Declaration for public API function in file dbdata.c. This may be called
** with NULL as the final two arguments to register the sqlite_dbptr and
** sqlite_dbdata virtual tables with a database handle.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*);
/*
** sqlite3_recover_init DB DBNAME URI
*/
static int test_sqlite3_dbdata_init(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db = 0;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, objv[1], &db) ) return TCL_ERROR;
sqlite3_dbdata_init(db, 0, 0);
Tcl_ResetResult(interp);
return TCL_OK;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int TestRecover_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
struct Cmd {
const char *zCmd;
Tcl_ObjCmdProc *xProc;
void *pArg;
} aCmd[] = {
{ "sqlite3_recover_init", test_sqlite3_recover_init, 0 },
{ "sqlite3_recover_init_sql", test_sqlite3_recover_init, (void*)1 },
{ "sqlite3_dbdata_init", test_sqlite3_dbdata_init, (void*)1 },
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){
struct Cmd *p = &aCmd[i];
Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, p->pArg, 0);
}
#endif
return TCL_OK;
}