/ Check-in [10f9e39d]
Login

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

Overview
Comment:More aggressive early detection of orphaned and malformed autoindexes when parsing the schema.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:10f9e39d6ed2413fa9abc6c82da3ed48f32a42b6190b6219fca7faf850d05113
User & Date: drh 2019-01-10 14:33:15
Context
2019-01-10
15:17
Fix further problems with fts5 handling corrupt databases. check-in: 83c467d7 user: dan tags: trunk
14:33
More aggressive early detection of orphaned and malformed autoindexes when parsing the schema. check-in: 10f9e39d user: drh tags: trunk
13:56
Use the new SQLITE_IDXTYPE_IPK values (3) on Index.idxType to indicate the fake INTEGER PRIMARY KEY index used during query planning. check-in: e22d2f90 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/prepare.c.

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136
137
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
    if( pIndex==0 ){
      /* This can occur if there exists an index on a TEMP table which
      ** has the same name as another index on a permanent index.  Since
      ** the permanent table is hidden by the TEMP table, we can also
      ** safely ignore the index on the permanent table.
      */
      /* Do Nothing */;
    }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){


      corruptSchema(pData, argv[0], "invalid rootpage");
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal







|
<
<
<
<
<
<
|
>
>
|







115
116
117
118
119
120
121
122






123
124
125
126
127
128
129
130
131
132
133
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
    if( pIndex==0






     || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
     || pIndex->tnum<2
    ){
      corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal

Changes to test/dbfuzz001.test.

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    |    432: 01 ec 01 c5 01 0d 43 00 00 48 01 54 00 01 f7 01   ......C..H.T....
    |    448: ec 01 c5 01 0d 42 00 00 48 01 54 00 01 f7 01 ec   .....B..H.T.....
    |    464: 01 c5 01 0d 41 00 00 48 01 54 00 01 f7 01 ec 01   ....A..H.T......
    |    480: c5 01 0d 40 00 00 48 01 54 00 01 f7 01 ec 01 c5   ...@..H.T.......
    |    496: 01 0d 3f 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   ..?..H.T........
    | end c4.db
  }]
  db eval {PRAGMA integrity_check}
} {/Fragmentation of 384 bytes reported as 0 on page 8/}

# The DELETE query below deletes the very last cell from page 8.
# Prior to a certain fix to sqlite3BtreeDelete() and because of the
# corruption to the freeblock list on page 8, this would fail to
# cause a rebalance operation, which would leave the btree in a weird
# state that would lead to segfaults and or assertion faults.







|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    |    432: 01 ec 01 c5 01 0d 43 00 00 48 01 54 00 01 f7 01   ......C..H.T....
    |    448: ec 01 c5 01 0d 42 00 00 48 01 54 00 01 f7 01 ec   .....B..H.T.....
    |    464: 01 c5 01 0d 41 00 00 48 01 54 00 01 f7 01 ec 01   ....A..H.T......
    |    480: c5 01 0d 40 00 00 48 01 54 00 01 f7 01 ec 01 c5   ...@..H.T.......
    |    496: 01 0d 3f 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   ..?..H.T........
    | end c4.db
  }]
  db eval {PRAGMA writable_schema=on; PRAGMA integrity_check}
} {/Fragmentation of 384 bytes reported as 0 on page 8/}

# The DELETE query below deletes the very last cell from page 8.
# Prior to a certain fix to sqlite3BtreeDelete() and because of the
# corruption to the freeblock list on page 8, this would fail to
# cause a rebalance operation, which would leave the btree in a weird
# state that would lead to segfaults and or assertion faults.

Changes to test/fts3corrupt4.test.

243
244
245
246
247
248
249
250
251
252
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end c15.db
}]} {}

do_catchsql_test 5.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {database disk image is malformed}}

finish_test







|


243
244
245
246
247
248
249
250
251
252
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end c15.db
}]} {}

do_catchsql_test 5.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {malformed database schema (sqlite_autoindey_t1_segdir_1) - orphan index}}

finish_test

Changes to test/fts3fuzz001.test.

86
87
88
89
90
91
92

93
94
95
96
97
98
99
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
|   4064: 69 74 79 3d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity=check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end c6.db
  }]
  catchsql {

    INSERT INTO t1(t1) SELECT x FROM t2;
  }
} {1 {database disk image is malformed}}
do_test fts3fuzz001-110 {
  catchsql {
    INSERT INTO t1(t1) VALUES('integrity-check');
  }







>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
|   4064: 69 74 79 3d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity=check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end c6.db
  }]
  catchsql {
    PRAGMA writable_schema=on; -- disable schema corruption detection
    INSERT INTO t1(t1) SELECT x FROM t2;
  }
} {1 {database disk image is malformed}}
do_test fts3fuzz001-110 {
  catchsql {
    INSERT INTO t1(t1) VALUES('integrity-check');
  }