]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a buffer overread in fts3 that can occur if the database is corrupt.
authordan <dan@noemail.net>
Wed, 27 Oct 2010 16:52:27 +0000 (16:52 +0000)
committerdan <dan@noemail.net>
Wed, 27 Oct 2010 16:52:27 +0000 (16:52 +0000)
FossilOrigin-Name: 84194c4195d7144ff7f9cedcdc74fdd908f3bfcd

ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3corrupt.test [new file with mode: 0644]
test/fts3defer2.test

index 2bb5fb9c1378e68d1ef231f39a3b13807bed28a7..50dafe06ee285c944904f82e291f3055b13c510a 100644 (file)
@@ -916,9 +916,19 @@ static int fts3SegReaderNext(Fts3Table *p, Fts3SegReader *pReader){
   pReader->nTerm = nPrefix+nSuffix;
   pNext += nSuffix;
   pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
-  assert( pNext<&pReader->aNode[pReader->nNode] );
   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;
 }
 
index 055fab59389d07d4d2ebc1c2a77d6a5dbbcce616..8fbcf3fb0ee864c29d0f61f89c5b04d7fb67c22c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C In\sfts4,\sstore\sthe\stotal\snumber\sof\sbytes\sof\sfor\sall\srecords\sin\sthe\stable\sin\sthe\s%_stat\stable.
-D 2010-10-27T10:55:54
+C Fix\sa\sbuffer\soverread\sin\sfts3\sthat\scan\soccur\sif\sthe\sdatabase\sis\scorrupt.
+D 2010-10-27T16:52:27
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -73,7 +73,7 @@ F ext/fts3/fts3_snippet.c 300c12b7f0a2a6ae0491bb2d00e2d5ff9c28f685
 F ext/fts3/fts3_tokenizer.c b4f2d01c24573852755bc92864816785dae39318
 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
-F ext/fts3/fts3_write.c 943216b144447a1fbadef373cbd2b7eb3fd17a65
+F ext/fts3/fts3_write.c a9189fa8719158b695f33e1490f56256308e2525
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@@ -431,10 +431,11 @@ F test/fts3ao.test b83f99f70e9eec85f27d75801a974b3f820e01f9
 F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
 F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
+F test/fts3corrupt.test 8d2ef629be9eff997db32ec3f0f7b53b0c61d086
 F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
 F test/fts3defer.test eab4f24c8402fb4e1e6aad44bcdfbe5bf42160b2
-F test/fts3defer2.test 1a9f213ca79509b60d81460febc7e4e5b64af95c
+F test/fts3defer2.test d3c7db6584aab06a2781b8de58747c33b23cb19c
 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
@@ -879,7 +880,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 97c6b2616ddcce2337778c6ee88a973cc4fe999d
-R 8864817f6f3963775cfdd60519bb3822
+P 941647d121ac60e2eabc998cfe79b157fb918d7e
+R 4228d3b4dbf28842cbc96083972fc4a8
 U dan
-Z 890501f0776b5167d933a1fceff6796c
+Z 82331704b60d2b02d0a92d3a85b091f9
index 9e8bb976fe1e53c0b70b19ecaa0835ce4881660f..ae661d2bc4a3b3a7d1e4a176037c38cdbb162b63 100644 (file)
@@ -1 +1 @@
-941647d121ac60e2eabc998cfe79b157fb918d7e
\ No newline at end of file
+84194c4195d7144ff7f9cedcdc74fdd908f3bfcd
\ No newline at end of file
diff --git a/test/fts3corrupt.test b/test/fts3corrupt.test
new file mode 100644 (file)
index 0000000..217ef94
--- /dev/null
@@ -0,0 +1,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
+
index 7bf4210f13789a36fa00edb9e1e8e41bdf6cd9d8..ccae5bc3da0217d031015a4cfb4bac0578187891 100644 (file)
@@ -36,15 +36,16 @@ 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');
-  UPDATE t1_segments 
-    SET block = zeroblob(length(block)) 
-    WHERE length(block)>10000;
 }
 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;
+  UPDATE t1_segments SET block = zeroblob(length(block)) WHERE length(block)>10000;
 } {2}
 
 do_execsql_test 1.2.1 {
@@ -57,7 +58,7 @@ do_execsql_test 1.2.2 {
 } [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 3 3   1 3 3   3 13336 9]
+   [list 3 1   1 1 1   1 8 8   1 8 8   8 5001 9]
 ]
 
 do_execsql_test 1.2.3 {
@@ -66,7 +67,7 @@ do_execsql_test 1.2.3 {
 } [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 3 3   2 3 3   3 13336 9]
+   [list 3 1   1 1 1   1 8 8   2 8 8   8 5001 9]
 ]
 
 do_execsql_test 1.3.1 { DROP TABLE t1 }
@@ -104,6 +105,12 @@ do_execsql_test 2.3.1 {
   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]')
@@ -118,7 +125,7 @@ foreach {tn sql} {
   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 5 2006 6} 3 {1 1 1 4 4 5 2006 6}}
+  } {1 {1 1 1 4 4 11 912 6} 3 {1 1 1 4 4 11 912 6}}
 }