/ Check-in [bc78235f]
Login

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

Overview
Comment:Improved the interface to the fts5() extension mechanism for enhanced security.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.20
Files: files | file ages | folders
SHA3-256: bc78235f547977f1a821342ca8f3e03103a0eb351f8b3115ac10b43dd9c7044d
User & Date: drh 2017-07-17 15:38:57
Context
2017-07-17
17:46
Interchange to branches within an "if" statement in sqlite3_value_pointer() in order to work around a bug in gcc. Closed-Leaf check-in: 8a606e4a user: drh tags: branch-3.20
15:38
Improved the interface to the fts5() extension mechanism for enhanced security. check-in: bc78235f user: drh tags: branch-3.20
12:41
Comment changes clarifying details of the pointer-type parameter. No changes to code. check-in: e4579e50 user: drh tags: branch-3.20
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_main.c.

  2605   2605   
  2606   2606     sqlite3_free(pGlobal);
  2607   2607   }
  2608   2608   
  2609   2609   static void fts5Fts5Func(
  2610   2610     sqlite3_context *pCtx,          /* Function call context */
  2611   2611     int nArg,                       /* Number of args */
  2612         -  sqlite3_value **apUnused        /* Function arguments */
         2612  +  sqlite3_value **apArg           /* Function arguments */
  2613   2613   ){
  2614   2614     Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
  2615         -  char buf[8];
  2616         -  UNUSED_PARAM2(nArg, apUnused);
  2617         -  assert( nArg==0 );
  2618         -  assert( sizeof(buf)>=sizeof(pGlobal) );
  2619         -  memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
  2620         -  sqlite3_result_blob(pCtx, buf, sizeof(pGlobal), SQLITE_TRANSIENT);
         2615  +  fts5_api **ppApi;
         2616  +  UNUSED_PARAM(nArg);
         2617  +  assert( nArg==1 );
         2618  +  ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
         2619  +  if( ppApi ) *ppApi = &pGlobal->api;
  2621   2620   }
  2622   2621   
  2623   2622   /*
  2624   2623   ** Implementation of fts5_source_id() function.
  2625   2624   */
  2626   2625   static void fts5SourceIdFunc(
  2627   2626     sqlite3_context *pCtx,          /* Function call context */
................................................................................
  2678   2677       if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
  2679   2678       if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
  2680   2679       if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
  2681   2680       if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
  2682   2681       if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
  2683   2682       if( rc==SQLITE_OK ){
  2684   2683         rc = sqlite3_create_function(
  2685         -          db, "fts5", 0, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
         2684  +          db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
  2686   2685         );
  2687   2686       }
  2688   2687       if( rc==SQLITE_OK ){
  2689   2688         rc = sqlite3_create_function(
  2690   2689             db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
  2691   2690         );
  2692   2691       }

Changes to ext/fts5/fts5_tcl.c.

    95     95     int rc = f5tDbPointer(interp, pObj, &db);
    96     96     if( rc!=TCL_OK ){
    97     97       return TCL_ERROR;
    98     98     }else{
    99     99       sqlite3_stmt *pStmt = 0;
   100    100       fts5_api *pApi = 0;
   101    101   
   102         -    rc = sqlite3_prepare_v2(db, "SELECT fts5()", -1, &pStmt, 0);
          102  +    rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
   103    103       if( rc!=SQLITE_OK ){
   104    104         Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
   105    105         return TCL_ERROR;
   106    106       }
   107         -
   108         -    if( SQLITE_ROW==sqlite3_step(pStmt) ){
   109         -      const void *pPtr = sqlite3_column_blob(pStmt, 0);
   110         -      memcpy((void*)&pApi, pPtr, sizeof(pApi));
   111         -    }
          107  +    sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr");
          108  +    sqlite3_step(pStmt);
   112    109   
   113    110       if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
   114    111         Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
   115    112         return TCL_ERROR;
   116    113       }
   117    114   
   118    115       *ppDb = db;

Changes to ext/fts5/fts5_test_mi.c.

    69     69   ** handle (accessible using sqlite3_errcode()/errmsg()).
    70     70   */
    71     71   static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
    72     72     sqlite3_stmt *pStmt = 0;
    73     73     int rc;
    74     74   
    75     75     *ppApi = 0;
    76         -  rc = sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0);
           76  +  rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0);
    77     77     if( rc==SQLITE_OK ){
    78         -    if( SQLITE_ROW==sqlite3_step(pStmt) 
    79         -        && sizeof(fts5_api*)==sqlite3_column_bytes(pStmt, 0)
    80         -      ){
    81         -      memcpy(ppApi, sqlite3_column_blob(pStmt, 0), sizeof(fts5_api*));
    82         -    }
           78  +    sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr");
           79  +    (void)sqlite3_step(pStmt);
    83     80       rc = sqlite3_finalize(pStmt);
    84     81     }
    85     82   
    86     83     return rc;
    87     84   }
    88     85   
    89     86   
................................................................................
   418    415     /* Register the implementation of matchinfo() */
   419    416     rc = pApi->xCreateFunction(pApi, "matchinfo", 0, fts5MatchinfoFunc, 0);
   420    417   
   421    418     return rc;
   422    419   }
   423    420   
   424    421   #endif /* SQLITE_ENABLE_FTS5 */
   425         -

Changes to ext/fts5/test/fts5matchinfo.test.

   468    468   } ;# foreach_detail_mode
   469    469   
   470    470   #-------------------------------------------------------------------------
   471    471   # Test that a bad fts5() return is detected
   472    472   #
   473    473   reset_db
   474    474   proc xyz {} {}
   475         -db func fts5 -argcount 0 xyz
          475  +db func fts5 -argcount 1 xyz
   476    476   do_test 13.1 {
   477    477     list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg
   478    478   } {1 SQLITE_ERROR}
   479    479   
   480    480   #-------------------------------------------------------------------------
   481    481   # Test that an invalid matchinfo() flag is detected
   482    482   #