xref: /sqlite-3.40.0/test/corruptJ.test (revision af3906a7)
1116f0be0Sdrh# 2015-03-30
2116f0be0Sdrh#
3116f0be0Sdrh# The author disclaims copyright to this source code.  In place of
4116f0be0Sdrh# a legal notice, here is a blessing:
5116f0be0Sdrh#
6116f0be0Sdrh#    May you do good and not evil.
7116f0be0Sdrh#    May you find forgiveness for yourself and forgive others.
8116f0be0Sdrh#    May you share freely, never taking more than you give.
9116f0be0Sdrh#
10116f0be0Sdrh#***********************************************************************
11116f0be0Sdrh#
12116f0be0Sdrh# Corruption consisting of a database page that thinks it is a child
13116f0be0Sdrh# of itself.
14116f0be0Sdrh#
15116f0be0Sdrh
16116f0be0Sdrhset testdir [file dirname $argv0]
17116f0be0Sdrhsource $testdir/tester.tcl
18116f0be0Sdrhset testprefix corruptJ
19116f0be0Sdrh
20116f0be0Sdrhif {[permutation]=="mmap"} {
21116f0be0Sdrh  finish_test
22116f0be0Sdrh  return
23116f0be0Sdrh}
24116f0be0Sdrh
25*af3906a7Sdrh# This module uses hard-coded offsets which do not work if the reserved_bytes
26*af3906a7Sdrh# value is nonzero.
27*af3906a7Sdrhif {[nonzero_reserved_bytes]} {finish_test; return;}
28*af3906a7Sdrh
29116f0be0Sdrhdatabase_may_be_corrupt
30116f0be0Sdrh
31116f0be0Sdrh# Initialize the database.
32116f0be0Sdrh#
33116f0be0Sdrhdo_execsql_test 1.1 {
34116f0be0Sdrh  PRAGMA page_size=1024;
35116f0be0Sdrh  PRAGMA auto_vacuum=0;
36116f0be0Sdrh  CREATE TABLE t1(a,b);
37116f0be0Sdrh  WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
38116f0be0Sdrh    INSERT INTO t1(a,b) SELECT i, zeroblob(700) FROM c;
39116f0be0Sdrh} {}
40116f0be0Sdrhdb close
41116f0be0Sdrh
42116f0be0Sdrh# Corrupt the root page of the t1 table such that the left-child pointer
43116f0be0Sdrh# for the very first cell points back to the root.  Then try to DROP the
44116f0be0Sdrh# table.  The clearDatabasePage() routine should not loop.
45116f0be0Sdrh#
46116f0be0Sdrhdo_test 1.2 {
47116f0be0Sdrh  hexio_write test.db [expr {2*1024-2}] 02
48116f0be0Sdrh  sqlite3 db test.db
49116f0be0Sdrh  catchsql { DROP TABLE t1 }
50116f0be0Sdrh} {1 {database disk image is malformed}}
51116f0be0Sdrh
52116f0be0Sdrh# Similar test using a WITHOUT ROWID table
53116f0be0Sdrh#
54116f0be0Sdrhdo_test 2.1 {
55116f0be0Sdrh  db close
56116f0be0Sdrh  forcedelete test.db
57116f0be0Sdrh  sqlite3 db test.db
58116f0be0Sdrh  db eval {
59116f0be0Sdrh    PRAGMA page_size=1024;
60116f0be0Sdrh    PRAGMA auto_vacuum=0;
61116f0be0Sdrh    CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
62116f0be0Sdrh    WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100)
63116f0be0Sdrh      INSERT INTO t1(a,b) SELECT i, zeroblob(200) FROM c;
64116f0be0Sdrh  }
65116f0be0Sdrh} {}
66116f0be0Sdrh
67116f0be0Sdrh# The table is three levels deep.  Corrupt the left child of an intermediate
68116f0be0Sdrh# page so that it points back to the root page.
69116f0be0Sdrh#
70116f0be0Sdrhdo_test 2.2 {
71116f0be0Sdrh  db close
72116f0be0Sdrh  hexio_read test.db [expr {9*1024+391}] 8
73116f0be0Sdrh} {00000008814D0401}
74116f0be0Sdrhdo_test 2.2b {
75116f0be0Sdrh  hexio_write test.db [expr {9*1024+391}] 00000002
76116f0be0Sdrh  sqlite3 db test.db
7796e28569Sdrh  catchsql { PRAGMA secure_delete=ON; DROP TABLE t1; }
7896e28569Sdrh} {1 {database disk image is malformed}}
79116f0be0Sdrh
80116f0be0Sdrhfinish_test
81