SQLite

Check-in [c73d915923]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Test that single byte corruptions in increasingly larger quantities are handled gracefully. (CVS 5854)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c73d915923e393f72e1c0897526a20527db2e03c
User & Date: shane 2008-10-31 13:57:40.000
Context
, (SELECT ... FROM tbl WHERE rowid > ) FROM ...". (CVS 5855) (check-in: 6c918c4eb9 user: danielk1977 tags: trunk)
2008-11-03
09:06
Fix a bug reported on the mailing list triggered by the pattern "SELECT
2008-10-31
13:57
Test that single byte corruptions in increasingly larger quantities are handled gracefully. (CVS 5854) (check-in: c73d915923 user: shane tags: trunk)
10:53
Change the way sqlite3VdbeSetColName() is called so as to remove a few lines of code. This also fixes #3470. (CVS 5853) (check-in: bfce91429b user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Added test/corruptC.test.






































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# 2004 August 30
#
# 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 implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.  It creates a base
# data base file, then tests that single byte corruptions in 
# increasingly larger quantities are handled gracefully.
#
# $Id: corruptC.test,v 1.1 2008/10/31 13:57:40 shane Exp $

catch {file delete -force test.db test.db-journal test.bu}

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Construct a compact, dense database for testing.
#
do_test corruptC-1.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    INSERT OR IGNORE INTO t1 SELECT x*2 FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*3 FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*5 FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*7 FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*11 FROM t1;
    INSERT OR IGNORE INTO t1 SELECT x*13 FROM t1;
    CREATE INDEX t1i1 ON t1(x);
    CREATE TABLE t2 AS SELECT * FROM t1 WHERE rowid%5!=0;
    COMMIT;
  }
} {}

ifcapable {integrityck} {
  integrity_check corruptC-1.2
}

# Generate random integer
#
proc random {range} {
    return [expr {round(rand()*$range)}]
}

# Copy file $from into $to
#
proc copy_file {from to} {
  set f [open $from]
  fconfigure $f -translation binary
  set t [open $to w]
  fconfigure $t -translation binary
  puts -nonewline $t [read $f [file size $from]]
  close $t
  close $f
}

# Setup for the tests.  Make a backup copy of the good database in test.bu.
#
copy_file test.db test.bu
set fsize [file size test.db]

for {set tn 1} {$tn<=1024} {incr tn 1} {

  # setup for test
  db close
  copy_file test.bu test.db

  # Seek to a random location in the file, and write a random single byte
  # value.  Then do various operations on the file to make sure that
  # the database engine can handle the corruption gracefully.
  #
  set last 0
  for {set i 1} {$i<=1024 && !$last} {incr i 1} {

    # insert random byte at random location
    set fd [open test.db r+]
    fconfigure $fd -translation binary
    seek $fd [random $fsize]
    puts -nonewline $fd [format "%c" [expr [random 255]]]
    close $fd

    # do a few random operations to make sure that if 
    # they error, they error gracefully instead of crashing.
    do_test corruptC-2.$tn.$i.1 {
      sqlite3 db test.db
      catchsql {SELECT count(*) FROM sqlite_master}
      set x {}
    } {}
    do_test corruptC-2.$tn.$i.2 {
      catchsql {SELECT count(*) FROM t1}
      set x {}
    } {}
    do_test corruptC-2.$tn.$i.3 {
      catchsql {SELECT count(*) FROM t1 WHERE x>13}
      set x {}
    } {}
    do_test corruptC-2.$tn.$i.4 {
      catchsql {SELECT count(*) FROM t2}
      set x {}
    } {}
    do_test corruptC-2.$tn.$i.5 {
      catchsql {SELECT count(*) FROM t2 WHERE x<13}
      set x {}
    } {}

    # check the integrity of the database.
    # once the corruption is detected, we can stop.
    ifcapable {integrityck} {
      set res [ catchsql {PRAGMA integrity_check} ]
      set ans [lindex $res 1]
      if { [ string compare $ans "ok" ] != 0 } {
        set last -1
      }
    }
    # if we are not capable of doing an integrity check,
    # stop after corrupting 5 bytes.
    ifcapable {!integrityck} {
      if { $i > 5 } {
        set last -1
      }
    }

    # Check that no page references were leaked.
    do_test corruptC-2.$tn.$i.6 {
      set bt [btree_from_db db]
      db_enter db
      array set stats [btree_pager_stats $bt]
      db_leave db
      set stats(ref)
    } {0}

  }
  # end for i

}
# end for tn

finish_test