1 From ab29deaf1d9911e7dfc5f12e1fb131f800c9d4fd Mon Sep 17 00:00:00 2001
2 From: cpu <cpu@chromium.org>
3 Date: Mon, 14 Sep 2009 17:37:35 +0000
4 Subject: [PATCH 15/16] [fts2] Fix a crasher in full text search (sqlite)
6 - If the xxx_segdir table gets corrupted, you can have non-contiguous indexes (idx).
7 - This causes an assertion in debug, and a crash later on on release
9 With this change it will return 'corrupted db'
11 We shall wait to get a couple more fixes to upstream to sqlite org.
16 Original review URL: https://codereview.chromium.org/203046
22 fixup [open][fts2] Tweak Carlos' change to cater for the additional cases:
23 - More (ordered) segments than we expect - would previously cause stack-based
25 - Less segments than we expect, where the missing segments are a strict
26 truncation rather than missing in the middle.
31 Original review URL: https://codereview.chromium.org/209001/
33 third_party/sqlite/src/ext/fts2/fts2.c | 15 +++++++++++----
34 1 file changed, 11 insertions(+), 4 deletions(-)
36 diff --git a/third_party/sqlite/src/ext/fts2/fts2.c b/third_party/sqlite/src/ext/fts2/fts2.c
37 index 5cb3fc6..a78e3d3 100644
38 --- a/third_party/sqlite/src/ext/fts2/fts2.c
39 +++ b/third_party/sqlite/src/ext/fts2/fts2.c
40 @@ -1838,7 +1838,7 @@ static const char *const fulltext_zStatement[MAX_STMT] = {
41 /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?",
42 /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)",
43 /* SEGDIR_SELECT_LEVEL */
44 - "select start_block, leaves_end_block, root from %_segdir "
45 + "select start_block, leaves_end_block, root, idx from %_segdir "
46 " where level = ? order by idx",
48 "select min(start_block), max(end_block) from %_segdir "
49 @@ -5287,16 +5287,19 @@ static int leavesReadersInit(fulltext_vtab *v, int iLevel,
50 sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
51 const char *pRootData = sqlite3_column_blob(s, 2);
52 int nRootData = sqlite3_column_bytes(s, 2);
53 + sqlite_int64 iIndex = sqlite3_column_int64(s, 3);
55 /* Corrupt if we get back different types than we stored. */
56 + /* Also corrupt if the index is not sequential starting at 0. */
57 if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER ||
58 sqlite3_column_type(s, 1)!=SQLITE_INTEGER ||
59 - sqlite3_column_type(s, 2)!=SQLITE_BLOB ){
60 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ||
63 rc = SQLITE_CORRUPT_BKPT;
67 - assert( i<MERGE_COUNT );
68 rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData,
70 if( rc!=SQLITE_OK ) break;
71 @@ -5391,10 +5394,14 @@ static int segmentMerge(fulltext_vtab *v, int iLevel){
72 memset(&lrs, '\0', sizeof(lrs));
73 rc = leavesReadersInit(v, iLevel, lrs, &i);
74 if( rc!=SQLITE_OK ) return rc;
75 - assert( i==MERGE_COUNT );
77 leafWriterInit(iLevel+1, idx, &writer);
79 + if( i!=MERGE_COUNT ){
80 + rc = SQLITE_CORRUPT_BKPT;
84 /* Since leavesReaderReorder() pushes readers at eof to the end,
85 ** when the first reader is empty, all will be empty.