Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a buffer overread in fts3 that can occur if the database is corrupt. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | experimental |
Files: | files | file ages | folders |
SHA1: |
84194c4195d7144ff7f9cedcdc74fdd9 |
User & Date: | dan 2010-10-27 16:52:27 |
Context
2010-10-27
| ||
18:10 | Merge experimental fts3/fts4 changes with trunk. (check-in: 988164cf user: dan tags: trunk) | |
16:52 | Fix a buffer overread in fts3 that can occur if the database is corrupt. (Closed-Leaf check-in: 84194c41 user: dan tags: experimental) | |
10:55 | In fts4, store the total number of bytes of for all records in the table in the %_stat table. (check-in: 941647d1 user: dan tags: experimental) | |
Changes
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
912 913 914 915 916 917 918 | pReader->zTerm = zNew; pReader->nTermAlloc = nNew; } memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); pReader->nTerm = nPrefix+nSuffix; pNext += nSuffix; pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist); | < > > > > > > > > > > > | 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | pReader->zTerm = zNew; pReader->nTermAlloc = nNew; } memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); pReader->nTerm = nPrefix+nSuffix; pNext += nSuffix; pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist); pReader->aDoclist = pNext; pReader->pOffsetList = 0; /* Check that the doclist does not appear to extend past the end of the ** b-tree node. And that the final byte of the doclist is either an 0x00 ** or 0x01. If either of these statements is untrue, then the data structure ** is corrupt. */ if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] || (pReader->aDoclist[pReader->nDoclist-1]&0xFE)!=0 ){ return SQLITE_CORRUPT; } return SQLITE_OK; } /* ** Set the SegReader to point to the first docid in the doclist associated ** with the current term. */ |
︙ | ︙ |
Added test/fts3corrupt.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 | # 2010 October 27 # # 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. # #*********************************************************************** # Test that the FTS3 extension does not crash when it encounters a # corrupt data structure on disk. # set testdir [file dirname $argv0] source $testdir/tester.tcl # If SQLITE_ENABLE_FTS3 is not defined, omit this file. ifcapable !fts3 { finish_test ; return } set ::testprefix fts3corrupt do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts3; INSERT INTO t1 VALUES('hello'); } {} do_test fts3corrupt-1.1 { set blob [db one {SELECT root from t1_segdir}] set blob [binary format a7ca* $blob 24 [string range $blob 8 end]] execsql { UPDATE t1_segdir SET root = $blob } } {} do_test fts3corrupt-1.2 { foreach w {a b c d e f g h i j k l m n o} { execsql { INSERT INTO t1 VALUES($w) } } } {} do_catchsql_test 1.3 { INSERT INTO t1 VALUES('world'); } {1 {database disk image is malformed}} finish_test |
Changes to test/fts3defer2.test.
︙ | ︙ | |||
32 33 34 35 36 37 38 39 | do_execsql_test 1.1.1 { CREATE VIRTUAL TABLE t1 USING fts4; } do_execsql_test 1.1.2 "INSERT INTO t1 VALUES('[string repeat {a } 20000]')" do_execsql_test 1.1.3 "INSERT INTO t1 VALUES('[string repeat {z } 20000]')" do_execsql_test 1.1.4 { INSERT INTO t1 VALUES('a b c d e f a x y'); INSERT INTO t1(t1) VALUES('optimize'); | > > > > > < < < < | | | | 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 | do_execsql_test 1.1.1 { CREATE VIRTUAL TABLE t1 USING fts4; } do_execsql_test 1.1.2 "INSERT INTO t1 VALUES('[string repeat {a } 20000]')" do_execsql_test 1.1.3 "INSERT INTO t1 VALUES('[string repeat {z } 20000]')" do_execsql_test 1.1.4 { INSERT INTO t1 VALUES('a b c d e f a x y'); INSERT INTO t1 VALUES(''); INSERT INTO t1 VALUES(''); INSERT INTO t1 VALUES(''); INSERT INTO t1 VALUES(''); INSERT INTO t1 VALUES(''); INSERT INTO t1(t1) VALUES('optimize'); } do_execsql_test 1.1.4 { SELECT count(*) FROM t1_segments WHERE length(block)>10000; UPDATE t1_segments SET block = zeroblob(length(block)) WHERE length(block)>10000; } {2} do_execsql_test 1.2.1 { SELECT content FROM t1 WHERE t1 MATCH 'f (e NEAR/2 a)'; } {{a b c d e f a x y}} do_execsql_test 1.2.2 { SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'f (e NEAR/2 a)'; } [list \ {a b c d [e] [f] [a] x y} \ {0 1 8 1 0 0 10 1 0 2 12 1} \ [list 3 1 1 1 1 1 8 8 1 8 8 8 5001 9] ] do_execsql_test 1.2.3 { SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'f (e NEAR/3 a)'; } [list \ {[a] b c d [e] [f] [a] x y} \ {0 2 0 1 0 1 8 1 0 0 10 1 0 2 12 1} \ [list 3 1 1 1 1 1 8 8 2 8 8 8 5001 9] ] do_execsql_test 1.3.1 { DROP TABLE t1 } #----------------------------------------------------------------------------- # Test cases fts3defer2-2.* focus specifically on the matchinfo function. # |
︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | do_execsql_test 2.3.1 { CREATE VIRTUAL TABLE t3 USING fts4; INSERT INTO t3 VALUES('a b c d e f'); INSERT INTO t3 VALUES('x b c d e f'); INSERT INTO t3 VALUES('d e f a b c'); INSERT INTO t3 VALUES('b c d e f'); } do_execsql_test 2.3.2 " INSERT INTO t3 VALUES('f e d c b [string repeat {a } 10000]') " foreach {tn sql} { 1 {} 2 { INSERT INTO t3(t3) VALUES('optimize') } 3 { UPDATE t3_segments SET block = zeroblob(length(block)) WHERE length(block)>10000; } } { execsql $sql do_execsql_test 2.4.$tn { SELECT docid, mit(matchinfo(t3)) FROM t3 WHERE t3 MATCH '"a b c"'; | > > > > > > | | 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 | do_execsql_test 2.3.1 { CREATE VIRTUAL TABLE t3 USING fts4; INSERT INTO t3 VALUES('a b c d e f'); INSERT INTO t3 VALUES('x b c d e f'); INSERT INTO t3 VALUES('d e f a b c'); INSERT INTO t3 VALUES('b c d e f'); INSERT INTO t3 VALUES(''); INSERT INTO t3 VALUES(''); INSERT INTO t3 VALUES(''); INSERT INTO t3 VALUES(''); INSERT INTO t3 VALUES(''); INSERT INTO t3 VALUES(''); } do_execsql_test 2.3.2 " INSERT INTO t3 VALUES('f e d c b [string repeat {a } 10000]') " foreach {tn sql} { 1 {} 2 { INSERT INTO t3(t3) VALUES('optimize') } 3 { UPDATE t3_segments SET block = zeroblob(length(block)) WHERE length(block)>10000; } } { execsql $sql do_execsql_test 2.4.$tn { SELECT docid, mit(matchinfo(t3)) FROM t3 WHERE t3 MATCH '"a b c"'; } {1 {1 1 1 4 4 11 912 6} 3 {1 1 1 4 4 11 912 6}} } finish_test |