/ Changes On Branch pass-pointer-as-blob
Login

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

Changes In Branch pass-pointer-as-blob Excluding Merge-Ins

This is equivalent to a diff from f39cb76b33 to 49cf31da82

2017-07-27
17:45
Add destructor functions for the pointer argument (NB: not the type string) to the sqlite3_bind_pointer() and sqlite3_result_pointer() interfaces. Use this new capability to resolve a pointer leak in the custom geometry function mechanism of the RTREE extension. (check-in: 5a2340b81f user: drh tags: branch-3.20)
14:04
A demonstration of how FTS3 cursor pointers can be passed from the MATCH operator to the snippet() function securely and opaquely without having to use the sqlite3_result_pointer() and sqlite3_value_pointer() interfaces. (Closed-Leaf check-in: 49cf31da82 user: drh tags: pass-pointer-as-blob)
03:48
Add a destructor argument to sqlite3_bind_pointer() and sqlite3_result_pointer(). (check-in: 3d9e841f60 user: drh tags: pointer-with-destructor)
2017-07-25
15:12
Release candidate 2 for 3.20.0. (check-in: f39cb76b33 user: drh tags: branch-3.20)
01:34
Fix a bug in the deterministic date/time function logic that can only appear with STAT3 or STAT4. (check-in: 1ca707a4fb user: drh tags: trunk)

Changes to ext/fts3/fts3.c.

3349
3350
3351
3352
3353
3354
3355

3356
3357
3358
3359
3360
3361
3362
3363

  /* The column value supplied by SQLite must be in range. */
  assert( iCol>=0 && iCol<=p->nColumn+2 );

  switch( iCol-p->nColumn ){
    case 0:
      /* The special 'table-name' column */

      sqlite3_result_pointer(pCtx, pCsr, "fts3cursor");
      break;

    case 1:
      /* The docid column */
      sqlite3_result_int64(pCtx, pCsr->iPrevId);
      break;








>
|







3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364

  /* The column value supplied by SQLite must be in range. */
  assert( iCol>=0 && iCol<=p->nColumn+2 );

  switch( iCol-p->nColumn ){
    case 0:
      /* The special 'table-name' column */
      pCsr->iMagic = FTS3_CURSOR_MAGIC;
      sqlite3_result_blob(pCtx, pCsr, 0, SQLITE_STATIC);
      break;

    case 1:
      /* The docid column */
      sqlite3_result_int64(pCtx, pCsr->iPrevId);
      break;

3568
3569
3570
3571
3572
3573
3574



3575


3576
3577
3578
3579
3580
3581
3582
3583
static int fts3FunctionArg(
  sqlite3_context *pContext,      /* SQL function call context */
  const char *zFunc,              /* Function name */
  sqlite3_value *pVal,            /* argv[0] passed to function */
  Fts3Cursor **ppCsr              /* OUT: Store cursor handle here */
){
  int rc;



  *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");


  if( (*ppCsr)!=0 ){
    rc = SQLITE_OK;
  }else{
    char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
    sqlite3_result_error(pContext, zErr, -1);
    sqlite3_free(zErr);
    rc = SQLITE_ERROR;
  }







>
>
>
|
>
>
|







3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
static int fts3FunctionArg(
  sqlite3_context *pContext,      /* SQL function call context */
  const char *zFunc,              /* Function name */
  sqlite3_value *pVal,            /* argv[0] passed to function */
  Fts3Cursor **ppCsr              /* OUT: Store cursor handle here */
){
  int rc;
  Fts3Cursor *pCur;
  if( sqlite3_value_type(pVal)==SQLITE_BLOB
   && sqlite3_value_bytes(pVal)==0
   && (pCur = (Fts3Cursor*)sqlite3_value_blob(pVal))!=0
   && pCur->iMagic==FTS3_CURSOR_MAGIC
  ){
    *ppCsr = pCur;
    rc = SQLITE_OK;
  }else{
    char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
    sqlite3_result_error(pContext, zErr, -1);
    sqlite3_free(zErr);
    rc = SQLITE_ERROR;
  }

Changes to ext/fts3/fts3Int.h.

286
287
288
289
290
291
292





293
294
295
296
297
298
299

300
301
302
303
304
305
306
#ifdef SQLITE_TEST
  /* True to disable the incremental doclist optimization. This is controled
  ** by special insert command 'test-no-incr-doclist'.  */
  int bNoIncrDoclist;
#endif
};






/*
** When the core wants to read from the virtual table, it creates a
** virtual table cursor (an instance of the following structure) using
** the xOpen method. Cursors are destroyed using the xClose method.
*/
struct Fts3Cursor {
  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */

  i16 eSearch;                    /* Search strategy (see below) */
  u8 isEof;                       /* True if at End Of Results */
  u8 isRequireSeek;               /* True if must seek pStmt to %_content row */
  u8 bSeekStmt;                   /* True if pStmt is a seek */
  sqlite3_stmt *pStmt;            /* Prepared statement in use by the cursor */
  Fts3Expr *pExpr;                /* Parsed MATCH query string */
  int iLangid;                    /* Language being queried for */







>
>
>
>
>







>







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
#ifdef SQLITE_TEST
  /* True to disable the incremental doclist optimization. This is controled
  ** by special insert command 'test-no-incr-doclist'.  */
  int bNoIncrDoclist;
#endif
};

/*
** Magic number for cursors
*/
#define FTS3_CURSOR_MAGIC  0x2f621809

/*
** When the core wants to read from the virtual table, it creates a
** virtual table cursor (an instance of the following structure) using
** the xOpen method. Cursors are destroyed using the xClose method.
*/
struct Fts3Cursor {
  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
  u32 iMagic;                     /* Magic number to prove identity */
  i16 eSearch;                    /* Search strategy (see below) */
  u8 isEof;                       /* True if at End Of Results */
  u8 isRequireSeek;               /* True if must seek pStmt to %_content row */
  u8 bSeekStmt;                   /* True if pStmt is a seek */
  sqlite3_stmt *pStmt;            /* Prepared statement in use by the cursor */
  Fts3Expr *pExpr;                /* Parsed MATCH query string */
  int iLangid;                    /* Language being queried for */

Changes to src/vdbeapi.c.

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  Mem *p = (Mem*)pVal;
  if( p->flags & (MEM_Blob|MEM_Str) ){
    if( ExpandBlob(p)!=SQLITE_OK ){
      assert( p->flags==MEM_Null && p->z==0 );
      return 0;
    }
    p->flags |= MEM_Blob;
    return p->n ? p->z : 0;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_bytes(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}







|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  Mem *p = (Mem*)pVal;
  if( p->flags & (MEM_Blob|MEM_Str) ){
    if( ExpandBlob(p)!=SQLITE_OK ){
      assert( p->flags==MEM_Null && p->z==0 );
      return 0;
    }
    p->flags |= MEM_Blob;
    return p->z; // p->n ? p->z : 0;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_bytes(sqlite3_value *pVal){
  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}