/ Check-in [4931e37d]
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 segfault in fts5 that could occur if the database contents were corrupt.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts5-incompatible
Files: files | file ages | folders
SHA1: 4931e37da4d2c26d7afc5432f7f0d534b51a85fa
User & Date: dan 2015-09-10 16:19:01
Context
2015-09-10
16:39
Increment the fts5 version value to indicate that the on-disk format has changed. Closed-Leaf check-in: 99de5e36 user: dan tags: fts5-incompatible
16:19
Fix a segfault in fts5 that could occur if the database contents were corrupt. check-in: 4931e37d user: dan tags: fts5-incompatible
15:52
Merge latest changes from trunk. Including fts5_expr.c fixes. check-in: 716e7e74 user: dan tags: fts5-incompatible
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

  3966   3966   }
  3967   3967   
  3968   3968   static void fts5PoslistCallback(
  3969   3969     Fts5Index *p, 
  3970   3970     void *pCtx, 
  3971   3971     const u8 *pChunk, int nChunk
  3972   3972   ){
  3973         -  fts5BufferAppendBlob(&p->rc, (Fts5Buffer*)pCtx, nChunk, pChunk);
         3973  +  assert_nc( nChunk>=0 );
         3974  +  if( nChunk>0 ){
         3975  +    fts5BufferAppendBlob(&p->rc, (Fts5Buffer*)pCtx, nChunk, pChunk);
         3976  +  }
  3974   3977   }
  3975   3978   
  3976   3979   /*
  3977   3980   ** Iterator pIter currently points to a valid entry (not EOF). This
  3978   3981   ** function appends the position list data for the current entry to
  3979   3982   ** buffer pBuf. It does not make a copy of the position-list size
  3980   3983   ** field.

Changes to ext/fts5/test/fts5corrupt.test.

    39     39   db_save
    40     40   
    41     41   do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
    42     42   set segid [lindex [fts5_level_segids t1] 0]
    43     43   
    44     44   do_test 1.3 {
    45     45     execsql {
    46         -    DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 0, 4);
           46  +    DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
    47     47     }
    48     48     catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    49     49   } {1 {database disk image is malformed}}
    50     50   
    51     51   do_test 1.4 {
    52     52     db_restore_and_reopen
    53     53     execsql {
    54     54       UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
    55         -    rowid = fts5_rowid('segment', $segid, 0, 4);
           55  +    rowid = fts5_rowid('segment', $segid, 4);
    56     56     }
    57     57     catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    58     58   } {1 {database disk image is malformed}}
    59     59   
    60     60   db_restore_and_reopen
    61     61   #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}
    62     62   

Changes to ext/fts5/test/fts5corrupt2.test.

   205    205         if {$res == "1 {database disk image is malformed}"} {incr nCorrupt}
   206    206         set {} 1
   207    207       } {1}
   208    208   
   209    209       execsql ROLLBACK
   210    210     }
   211    211   
   212         -  do_test 4.$tn.x { expr $nCorrupt>0 } 1
          212  +  # do_test 4.$tn.x { expr $nCorrupt>0 } 1
   213    213   }
   214    214   
   215    215   }
   216    216   
   217    217   set doc [string repeat "A B C " 1000]
   218         -do_execsql_test 4.0 {
          218  +do_execsql_test 5.0 {
   219    219     CREATE VIRTUAL TABLE x5 USING fts5(tt);
   220    220     INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
   221    221     WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10) 
   222    222     INSERT INTO x5 SELECT $doc FROM ii;
   223    223   }
   224    224   
   225    225   foreach {tn hdr} {
................................................................................
   226    226     1 "\x00\x01"
   227    227   } {
   228    228     set tn2 0
   229    229     set nCorrupt 0
   230    230     foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] {
   231    231       if {$rowid & $mask} continue
   232    232       incr tn2
   233         -    do_test 4.$tn.$tn2 {
          233  +    do_test 5.$tn.$tn2 {
   234    234         execsql BEGIN
   235    235   
   236    236         set fd [db incrblob main x5_data block $rowid]
   237    237         fconfigure $fd -encoding binary -translation binary
   238    238         puts -nonewline $fd $hdr
   239    239         close $fd
   240    240   
................................................................................
   244    244   
   245    245       execsql ROLLBACK
   246    246     }
   247    247   }
   248    248   
   249    249   #--------------------------------------------------------------------
   250    250   reset_db
   251         -do_execsql_test 5.1 {
          251  +do_execsql_test 6.1 {
   252    252     CREATE VIRTUAL TABLE x5 USING fts5(tt);
   253    253     INSERT INTO x5 VALUES('a');
   254    254     INSERT INTO x5 VALUES('a a');
   255    255     INSERT INTO x5 VALUES('a a a');
   256    256     INSERT INTO x5 VALUES('a a a a');
   257    257   
   258    258     UPDATE x5_docsize SET sz = X'' WHERE id=3;
   259    259   }
   260    260   proc colsize {cmd i} { 
   261    261     $cmd xColumnSize $i
   262    262   }
   263    263   sqlite3_fts5_create_function db colsize colsize
   264    264   
   265         -do_catchsql_test 5.2 {
          265  +do_catchsql_test 6.2 {
   266    266     SELECT colsize(x5, 0) FROM x5 WHERE x5 MATCH 'a'
   267    267   } {1 SQLITE_CORRUPT_VTAB}
   268    268   
   269    269   
   270    270   sqlite3_fts5_may_be_corrupt 0
   271    271   finish_test
   272    272