]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a case in fts4 where a corrupt %_stat table could lead to a crash.
authordan <dan@noemail.net>
Tue, 1 Feb 2011 17:55:48 +0000 (17:55 +0000)
committerdan <dan@noemail.net>
Tue, 1 Feb 2011 17:55:48 +0000 (17:55 +0000)
FossilOrigin-Name: 4ade96ce974244fc34bb97713d3cba10e3d33056

ext/fts3/fts3_snippet.c
ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3corrupt.test

index acf1786819ef73150c6b3f980081e88f9eaab5be..54371db1c8d8311592446731d3100fd6a3d00e26 100644 (file)
@@ -960,6 +960,7 @@ static int fts3MatchinfoSelectDoctotal(
 
   a = sqlite3_column_blob(pStmt, 0);
   a += sqlite3Fts3GetVarint(a, &nDoc);
+  if( nDoc==0 ) return SQLITE_CORRUPT;
   *pnDoc = (u32)nDoc;
 
   if( paLen ) *paLen = a;
@@ -1166,9 +1167,11 @@ static int fts3MatchinfoValues(
           if( rc==SQLITE_OK ){
             int iCol;
             for(iCol=0; iCol<pInfo->nCol; iCol++){
+              u32 iVal;
               sqlite3_int64 nToken;
               a += sqlite3Fts3GetVarint(a, &nToken);
-              pInfo->aMatchinfo[iCol] = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc);
+              iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc);
+              pInfo->aMatchinfo[iCol] = iVal;
             }
           }
         }
index 8197ce3f5a65919645fd1de941b23148caca74c4..00b389d88f67d802badcba5e37da16a87ff55922 100644 (file)
@@ -289,7 +289,7 @@ static int fts3SelectDocsize(
       sqlite3_bind_int64(pStmt, 1, iDocid);
     }
     rc = sqlite3_step(pStmt);
-    if( rc!=SQLITE_ROW ){
+    if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
       rc = sqlite3_reset(pStmt);
       if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT;
       pStmt = 0;
@@ -1102,16 +1102,18 @@ int sqlite3Fts3SegReaderCost(
       sqlite3_stmt *pStmt;
       sqlite3_int64 nDoc = 0;
       sqlite3_int64 nByte = 0;
+      const char *pEnd;
       const char *a;
+
       rc = sqlite3Fts3SelectDoctotal(p, &pStmt);
-      if( rc ) return rc;
+      if( rc!=SQLITE_OK ) return rc;
       a = sqlite3_column_blob(pStmt, 0);
-      if( a ){
-        const char *pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
-        a += sqlite3Fts3GetVarint(a, &nDoc);
-        while( a<pEnd ){
-          a += sqlite3Fts3GetVarint(a, &nByte);
-        }
+      assert( a );
+
+      pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
+      a += sqlite3Fts3GetVarint(a, &nDoc);
+      while( a<pEnd ){
+        a += sqlite3Fts3GetVarint(a, &nByte);
       }
       if( nDoc==0 || nByte==0 ){
         sqlite3_reset(pStmt);
index 76a7ca82f27752f5db55b93cd9e836a0aaa471fe..b0e047a5e68d5a9778df6bd7d47c9670b69c901b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\svirtual\stable\smodule\s"fts4aux",\sused\sto\sinspect\sthe\sfull-text\sindex\sof\san\sfts4\stable\sdirectly.\sAlso\sadd\sthe\s"compress"\sand\s"uncompress"\sfts4\soptions.
-D 2011-02-01T16:34:32.732
+C Fix\sa\scase\sin\sfts4\swhere\sa\scorrupt\s%_stat\stable\scould\slead\sto\sa\scrash.
+D 2011-02-01T17:55:48.046
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -69,11 +69,11 @@ F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c
 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
 F ext/fts3/fts3_icu.c ac494aed69835008185299315403044664bda295
 F ext/fts3/fts3_porter.c d61cfd81fb0fd8fbcb25adcaee0ba671aefaa5c2
-F ext/fts3/fts3_snippet.c 196c5e6cde57bfc1907c2d60e9c29590e4f93fb6
+F ext/fts3/fts3_snippet.c bfefb42b5debf8725a30fd5122572aaeedc99397
 F ext/fts3/fts3_tokenizer.c 055f3dc7369585350b28db1ee0f3b214dca6724d
 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
-F ext/fts3/fts3_write.c ae896d78e45cbbf7d1f37f4aaa4cb7e135c3ddb3
+F ext/fts3/fts3_write.c 58a4d891bd438ee279e82be7f2188b1885f56873
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@@ -441,7 +441,7 @@ F test/fts3aux1.test 9cf2e8499a494b92b77aaf1e5e1f50e4c4389549
 F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
 F test/fts3comp1.test ef36e5ddf9811c9801f52b2988bca1fce7dc8ce8
-F test/fts3corrupt.test d874ba27975aa8e5514bf58bf97b473404de0dbb
+F test/fts3corrupt.test 7890cc202406858386ddf390a879dcf80bc10abf
 F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
 F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
@@ -900,7 +900,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P ed759d5a9edb3bba5f48f243df47be29e3fe8cd7
-R 6973a45eacae0b4782da387c021f5c55
+P b010ddcc52889160af2183a33c5f483bb0ae91b9
+R 6357f23d94d26bf10b5519ed6d9a80e0
 U dan
-Z 7f4d4e13b48c27d8ce00c35eff8d5880
+Z 1245dae65401ccee7f129f9a4e09755d
index e222deedc26d0251ef6d89442e7ac15a6edea435..ea2b89631e2159c1024bbfb24eaa27d3c0685027 100644 (file)
@@ -1 +1 @@
-b010ddcc52889160af2183a33c5f483bb0ae91b9
\ No newline at end of file
+4ade96ce974244fc34bb97713d3cba10e3d33056
\ No newline at end of file
index c2889b8776473075e1d4018d8739e7f920c6ce69..b8b45c39518d03d9fd5f8721fd572118578701c3 100644 (file)
@@ -131,5 +131,32 @@ do_catchsql_test 4.3 {
   SELECT rowid FROM t1 WHERE t1 MATCH 'world';
 } {1 {database disk image is malformed}}
 
+# Test a special kind of corruption, where the %_stat table contains
+# an invalid entry. At one point this could lead to a division-by-zero
+# error in fts4.
+#
+do_execsql_test 5.0 {
+  DROP TABLE t1;
+  CREATE VIRTUAL TABLE t1 USING fts4;
+}
+do_test 5.1 {
+  db func nn nn
+  execsql BEGIN
+  execsql { INSERT INTO t1 VALUES('one') }
+  execsql { INSERT INTO t1 VALUES('two') }
+  execsql { INSERT INTO t1 VALUES('three') }
+  execsql { INSERT INTO t1 VALUES('four') }
+  execsql COMMIT
+} {}
+do_catchsql_test 5.2 {
+  UPDATE t1_stat SET value = X'0000';
+  SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*';
+} {1 {database disk image is malformed}}
+do_catchsql_test 5.3 {
+  UPDATE t1_stat SET value = NULL;
+  SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*';
+} {1 {database disk image is malformed}}
+
+
 finish_test