/ Check-in [928e6221]
Login

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

Overview
Comment:Avoid a division-by-zero error in fts5 caused by a corrupt database.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 928e622178bd004be52b2271ac554176aebe9d6e115ecac4e7072eccbb4262b5
User & Date: dan 2019-01-19 15:55:27
Context
2019-01-20
00:03
Add the --max-stack option to dbfuzz2. check-in: c11ae4fe user: drh tags: trunk
2019-01-19
15:55
Avoid a division-by-zero error in fts5 caused by a corrupt database. check-in: 928e6221 user: dan tags: trunk
15:27
Remove a broken assert() triggered by a "PRAGMA max_page_count = N" invocation, where N is larger than the number of pages in the database image, but smaller than the number of pages in the database file. check-in: 7cd56cad user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_aux.c.

   582    582         p->nPhrase = nPhrase;
   583    583         p->aIDF = (double*)&p[1];
   584    584         p->aFreq = &p->aIDF[nPhrase];
   585    585       }
   586    586   
   587    587       /* Calculate the average document length for this FTS5 table */
   588    588       if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
          589  +    assert( rc!=SQLITE_OK || nRow>0 );
   589    590       if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
   590    591       if( rc==SQLITE_OK ) p->avgdl = (double)nToken  / (double)nRow;
   591    592   
   592    593       /* Calculate an IDF for each phrase in the query */
   593    594       for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
   594    595         sqlite3_int64 nHit = 0;
   595    596         rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);

Changes to ext/fts5/fts5_storage.c.

  1074   1074     }
  1075   1075     return rc;
  1076   1076   }
  1077   1077   
  1078   1078   int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
  1079   1079     int rc = fts5StorageLoadTotals(p, 0);
  1080   1080     if( rc==SQLITE_OK ){
         1081  +    /* nTotalRow being zero does not necessarily indicate a corrupt 
         1082  +    ** database - it might be that the FTS5 table really does contain zero
         1083  +    ** rows. However this function is only called from the xRowCount() API,
         1084  +    ** and there is no way for that API to be invoked if the table contains
         1085  +    ** no rows. Hence the FTS5_CORRUPT return.  */
  1081   1086       *pnRow = p->nTotalRow;
         1087  +    if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
  1082   1088     }
  1083   1089     return rc;
  1084   1090   }
  1085   1091   
  1086   1092   /*
  1087   1093   ** Flush any data currently held in-memory to disk.
  1088   1094   */

Changes to ext/fts5/test/fts5corrupt3.test.

  4647   4647     SELECT quote(block) FROM t1_data WHERE rowid=10;
  4648   4648   } {X'000000000101010001010101'}
  4649   4649   
  4650   4650   do_execsql_test 37.1 {
  4651   4651     UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
  4652   4652     SELECT rowid FROM t1('a');
  4653   4653   } {1}
         4654  +
         4655  +#-------------------------------------------------------------------------
         4656  +reset_db 
         4657  +do_execsql_test 38.0 {
         4658  +  CREATE VIRTUAL TABLE t1 USING fts5(b, c);
         4659  +  INSERT INTO t1 VALUES('a', 'b');
         4660  +  INSERT INTO t1 VALUES('a', 'b');
         4661  +  SELECT quote(block) FROM t1_data WHERE rowid=1;
         4662  +} {X'020202'}
         4663  +
         4664  +do_execsql_test 38.1 {
         4665  +  SELECT * FROM t1('a b') ORDER BY rank;
         4666  +} {a b a b}
         4667  +
         4668  +do_execsql_test 38.2 {
         4669  +  UPDATE t1_data SET block = X'000202' WHERE rowid=1;
         4670  +}
         4671  +breakpoint
         4672  +do_catchsql_test 38.3 {
         4673  +  SELECT * FROM t1('a b') ORDER BY rank;
         4674  +} {1 {database disk image is malformed}}
         4675  +
         4676  +db close
         4677  +sqlite3 db test.db
         4678  +do_catchsql_test 38.4 {
         4679  +  SELECT * FROM t1('a b') ORDER BY rank;
         4680  +} {1 {database disk image is malformed}}
         4681  +
  4654   4682   
  4655   4683   
  4656   4684   
  4657   4685   sqlite3_fts5_may_be_corrupt 0
  4658   4686   finish_test
  4659   4687