SQLite

Check-in [505ed9a478]
Login

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

Overview
Comment:Avoid deferencing a freed pointer following an OOM or SQLITE_CORRUPT error in the fts3 xDestroy method.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 505ed9a47825240979338a24044559613fbbd2a7850bdff70c7164da054ec63d
User & Date: dan 2019-01-21 17:57:31.980
Context
2019-01-21
23:18
Enhance the btree search routine so that it does early detection of impossibly large keys and thereby avoids a large malloc() call. (check-in: 3ecaaee69f user: drh tags: trunk)
17:57
Avoid deferencing a freed pointer following an OOM or SQLITE_CORRUPT error in the fts3 xDestroy method. (check-in: 505ed9a478 user: dan tags: trunk)
16:12
Remove a faulty assert() from fts3. (check-in: 6c33a303eb user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3.c.
557
558
559
560
561
562
563
564
565
566
567
568
569
570







571
572
573
574
575
576
577
static int fts3DestroyMethod(sqlite3_vtab *pVtab){
  Fts3Table *p = (Fts3Table *)pVtab;
  int rc = SQLITE_OK;              /* Return code */
  const char *zDb = p->zDb;        /* Name of database (e.g. "main", "temp") */
  sqlite3 *db = p->db;             /* Database handle */

  /* Drop the shadow tables */
  if( p->zContentTbl==0 ){
    fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
  }
  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);








  /* If everything has worked, invoke fts3DisconnectMethod() to free the
  ** memory associated with the Fts3Table structure and return SQLITE_OK.
  ** Otherwise, return an SQLite error code.
  */
  return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc);
}







<
|
<
|
|
|
|
>
>
>
>
>
>
>







557
558
559
560
561
562
563

564

565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
static int fts3DestroyMethod(sqlite3_vtab *pVtab){
  Fts3Table *p = (Fts3Table *)pVtab;
  int rc = SQLITE_OK;              /* Return code */
  const char *zDb = p->zDb;        /* Name of database (e.g. "main", "temp") */
  sqlite3 *db = p->db;             /* Database handle */

  /* Drop the shadow tables */

  fts3DbExec(&rc, db, 

    "DROP TABLE IF EXISTS %Q.'%q_segments';"
    "DROP TABLE IF EXISTS %Q.'%q_segdir';"
    "DROP TABLE IF EXISTS %Q.'%q_docsize';"
    "DROP TABLE IF EXISTS %Q.'%q_stat';"
    "%s DROP TABLE IF EXISTS %Q.'%q_content';",
    zDb, p->zName,
    zDb, p->zName,
    zDb, p->zName,
    zDb, p->zName,
    (p->zContentTbl ? "--" : ""), zDb,p->zName
  );

  /* If everything has worked, invoke fts3DisconnectMethod() to free the
  ** memory associated with the Fts3Table structure and return SQLITE_OK.
  ** Otherwise, return an SQLite error code.
  */
  return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc);
}
Changes to test/fts3fault.test.
235
236
237
238
239
240
241
















242
243
do_faultsim_test 10.1 -prep {
  faultsim_delete_and_reopen
} -body {
  execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, languageid=d) }
} -test {
  faultsim_test_result {0 {}}
}

















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
do_faultsim_test 10.1 -prep {
  faultsim_delete_and_reopen
} -body {
  execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, languageid=d) }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.0 {
  CREATE VIRTUAL TABLE t1 USING fts3(a, b);
}
faultsim_save_and_close

do_faultsim_test 11 -faults oom* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { DROP TABLE t1 }
} -test {
  faultsim_test_result {0 {}}
}


finish_test