/ Check-in [811e12cd]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix a couple of crashes in fts3 that can occur if the database contents are inconsistent.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 811e12cddfb3246c6cf3d5085bd9b72b12e05550
User & Date: dan 2011-01-13 11:20:04
Context
2011-01-13
16:10
Fix a typo on the sqlite3_open_v2() documentation. check-in: b0add45a user: drh tags: trunk
11:20
Fix a couple of crashes in fts3 that can occur if the database contents are inconsistent. check-in: 811e12cd user: dan tags: trunk
10:58
Fix a segfault that can occur in matchinfo if an fts4 table contains mostly zero-length documents. Specifically, if the table contains more rows than it does bytes of text. check-in: fe904766 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3_write.c.

  1098   1098         ** varints, where nCol is the number of columns in the FTS3 table.
  1099   1099         ** The first varint is the number of documents currently stored in
  1100   1100         ** the table. The following nCol varints contain the total amount of
  1101   1101         ** data stored in all rows of each column of the table, from left
  1102   1102         ** to right.
  1103   1103         */
  1104   1104         sqlite3_stmt *pStmt;
  1105         -      rc = fts3SqlStmt(p, SQL_SELECT_DOCTOTAL, &pStmt, 0);
         1105  +      sqlite3_int64 nDoc = 0;
         1106  +      sqlite3_int64 nByte = 0;
         1107  +      const char *a;
         1108  +      rc = sqlite3Fts3SelectDoctotal(p, &pStmt);
  1106   1109         if( rc ) return rc;
  1107         -      if( sqlite3_data_count(pStmt) || sqlite3_step(pStmt)==SQLITE_ROW ){
  1108         -        sqlite3_int64 nDoc = 0;
  1109         -        sqlite3_int64 nByte = 0;
  1110         -        const char *a = sqlite3_column_blob(pStmt, 0);
  1111         -        if( a ){
  1112         -          const char *pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
  1113         -          a += sqlite3Fts3GetVarint(a, &nDoc);
  1114         -          while( a<pEnd ){
  1115         -            a += sqlite3Fts3GetVarint(a, &nByte);
  1116         -          }
         1110  +      a = sqlite3_column_blob(pStmt, 0);
         1111  +      if( a ){
         1112  +        const char *pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
         1113  +        a += sqlite3Fts3GetVarint(a, &nDoc);
         1114  +        while( a<pEnd ){
         1115  +          a += sqlite3Fts3GetVarint(a, &nByte);
  1117   1116           }
         1117  +      }
         1118  +      if( nDoc==0 || nByte==0 ){
         1119  +        sqlite3_reset(pStmt);
         1120  +        return SQLITE_CORRUPT;
         1121  +      }
  1118   1122   
  1119         -        pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz) / pgsz);
  1120         -        assert( pCsr->nRowAvg>0 ); 
  1121         -      }
         1123  +      pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz) / pgsz);
         1124  +      assert( pCsr->nRowAvg>0 ); 
  1122   1125         rc = sqlite3_reset(pStmt);
  1123         -      if( rc!=SQLITE_OK || pCsr->nRowAvg==0 ) return rc;
         1126  +      if( rc!=SQLITE_OK ) return rc;
  1124   1127       }
  1125   1128   
  1126   1129       /* Assume that a blob flows over onto overflow pages if it is larger
  1127   1130       ** than (pgsz-35) bytes in size (the file-format documentation
  1128   1131       ** confirms this).
  1129   1132       */
  1130   1133       for(iBlock=pReader->iStartBlock; iBlock<=pReader->iLeafEndBlock; iBlock++){

Changes to test/fts3matchinfo.test.

   360    360     }
   361    361     execsql { INSERT INTO t11(t11) VALUES('optimize') }
   362    362   } {}
   363    363   do_execsql_test 8.3 {
   364    364     SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
   365    365   } {{204 1 3 3 0} {204 1 3 3 0} {204 1 3 3 0}}
   366    366   
          367  +# Corruption related tests.
          368  +do_execsql_test  8.4.1.1 { UPDATE t11_stat SET value = X'0000'; }
          369  +do_catchsql_test 8.5.1.2 {
          370  +  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
          371  +} {1 {database disk image is malformed}}
          372  +
          373  +do_execsql_test  8.4.2.1 { UPDATE t11_stat SET value = X'00'; }
          374  +do_catchsql_test 8.5.2.2 {
          375  +  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
          376  +} {1 {database disk image is malformed}}
          377  +
          378  +do_execsql_test  8.4.3.1 { UPDATE t11_stat SET value = NULL; }
          379  +do_catchsql_test 8.5.3.2 {
          380  +  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
          381  +} {1 {database disk image is malformed}}
          382  +
   367    383   finish_test
   368    384