/ Check-in [6d91a1e9]
Login

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

Overview
Comment:Detect database corruption in rootpage flags (see also (2313)). (CVS 2314)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6d91a1e91bf0e8b4a0f5f78d079031f3ee69603b
User & Date: danielk1977 2005-02-05 06:49:54
Context
2005-02-05
07:33
Add a numeric version number. Ticket #1097. (CVS 2315) check-in: a9c33a80 user: danielk1977 tags: trunk
06:49
Detect database corruption in rootpage flags (see also (2313)). (CVS 2314) check-in: 6d91a1e9 user: danielk1977 tags: trunk
2005-02-04
21:13
Detect and report a subtle case of database file corruption. (CVS 2313) check-in: 9fc0a5cb user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1656
1657
1658
1659
1660
1661
1662



1663
1664

1665
1666

1667




1668
1669
1670
1671
1672
1673
1674
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.451 2005/02/04 21:13:01 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.



*/
case OP_SetNumColumns: {

  assert( (pOp->p1)<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );

  p->apCsr[pOp->p1]->nField = pOp->p2;




  break;
}

/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional







|







 







>
>
>


>


>
|
>
>
>
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.452 2005/02/05 06:49:54 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.
**
** If OP_KeyAsData is to be applied to cursor P1, it must be executed
** before this op-code.
*/
case OP_SetNumColumns: {
  Cursor *pC;
  assert( (pOp->p1)<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pC = p->apCsr[pOp->p1];
  pC->nField = pOp->p2;
  if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){
    rc = SQLITE_CORRUPT;
    goto abort_due_to_error;
  }
  break;
}

/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional

Changes to test/corrupt.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
107
108
109
110
111
112
113
114

























































115
#
#***********************************************************************
# 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.
#
# $Id: corrupt.test,v 1.5 2005/02/04 04:07:18 danielk1977 Exp $

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

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

................................................................................
    set x {}
  } {}
  do_test corrupt-2.$tn.7 {
    catchsql {PRAGMA integrity_check}
    set x {}
  } {}
}  


























































finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#
#***********************************************************************
# 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.
#
# $Id: corrupt.test,v 1.6 2005/02/05 06:49:55 danielk1977 Exp $

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

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

................................................................................
    set x {}
  } {}
  do_test corrupt-2.$tn.7 {
    catchsql {PRAGMA integrity_check}
    set x {}
  } {}
}  

#------------------------------------------------------------------------
# For these tests, swap the rootpage entries of t1 (a table) and t1i1 (an
# index on t1) in sqlite_master. Then perform a few different queries
# and make sure this is detected as corruption.
#
do_test corrupt-3.1 {
  db close
  copy_file test.bu test.db
  sqlite3 db test.db
  execsql {
    SELECT name, rootpage FROM sqlite_master
  }
} {t1 2 t1i1 85 t2 177}
do_test corrupt-3.2 {
  set t1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1i1'}]
  set t1i1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1'}]
  set cookie [expr [execsql {PRAGMA schema_version}] + 1]
  execsql "
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage = $t1_r WHERE name = 't1';
    UPDATE sqlite_master SET rootpage = $t1i1_r WHERE name = 't1i1';
    PRAGMA writable_schema = 0;
    PRAGMA schema_version = $cookie;
    SELECT name, rootpage FROM sqlite_master;
  "
} {t1 85 t1i1 2 t2 177}

# This one tests the case caught by code in checkin [2313].
do_test corrupt-3.3 {
  db close
  sqlite3 db test.db
  catchsql {
    INSERT INTO t1 VALUES('abc');
  }
} {1 {database disk image is malformed}}
do_test corrupt-3.4 {
  db close
  sqlite3 db test.db
  catchsql {
    SELECT * FROM t1;
  }
} {1 {database disk image is malformed}}
do_test corrupt-3.5 {
  db close
  sqlite3 db test.db
  catchsql {
    SELECT * FROM t1 WHERE oid = 10;
  }
} {1 {database disk image is malformed}}
do_test corrupt-3.6 {
  db close
  sqlite3 db test.db
  catchsql {
    SELECT * FROM t1 WHERE x = 'abcde';
  }
} {1 {database disk image is malformed}}

finish_test