/ Check-in [3bfee76f]
Login

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

Overview
Comment:Return SQLITE_MISUSE instead of crashing if NULL is (incorrectly) passed to sqlite3_step(). Ticket #2773. (CVS 4545)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3bfee76fa6191c6e3aaa4632949b53253c612f36
User & Date: danielk1977 2007-11-15 16:04:15
Context
2007-11-16
00:23
Don't do anything when input doclists are both empty. Ticket #2774 (CVS 4546) check-in: 75cb46f8 user: shess tags: trunk
2007-11-15
16:04
Return SQLITE_MISUSE instead of crashing if NULL is (incorrectly) passed to sqlite3_step(). Ticket #2773. (CVS 4545) check-in: 3bfee76f user: danielk1977 tags: trunk
13:10
Fix a segfault that can occur after a malloc failure in an ANALYZE statement. Ticket #2772. (CVS 4544) check-in: d05eb67d user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeapi.c.

251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
...
369
370
371
372
373
374
375
376

377
378
379
380
381

382
383
384
385


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
** schema change has occurred.  That detail is handled by the
** outer sqlite3_step() wrapper procedure.
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;


  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }

  /* Assert that malloc() has not failed */
  db = p->db;
  assert( !db->mallocFailed );

................................................................................
/*
** This is the top-level implementation of sqlite3_step().  Call
** sqlite3Step() to do most of the work.  If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
#ifdef SQLITE_OMIT_PARSER
int sqlite3_step(sqlite3_stmt *pStmt){
  int rc;

  Vdbe *v;
  v = (Vdbe*)pStmt;
  sqlite3_mutex_enter(v->db->mutex);
  rc = sqlite3Step(v);
  sqlite3_mutex_leave(v->db->mutex);

  return rc;
}
#else
int sqlite3_step(sqlite3_stmt *pStmt){


  int cnt = 0;
  int rc;
  Vdbe *v = (Vdbe*)pStmt;
  sqlite3 *db = v->db;
  sqlite3_mutex_enter(db->mutex);
  while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
         && cnt++ < 5
         && sqlite3Reprepare(v) ){
    sqlite3_reset(pStmt);
    v->expired = 0;
  }
  if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){
    /* This case occurs after failing to recompile an sql statement. 
    ** The error message from the SQL compiler has already been loaded 
    ** into the database handle. This block copies the error message 
    ** from the database handle into the statement and sets the statement
    ** program counter to 0 to ensure that when the statement is 
    ** finalized or reset the parser error message is available via
    ** sqlite3_errmsg() and sqlite3_errcode().
    */
    const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
    sqlite3_free(v->zErrMsg);
    if( !db->mallocFailed ){
      v->zErrMsg = sqlite3DbStrDup(db, zErr);
    } else {
      v->zErrMsg = 0;
      v->rc = SQLITE_NOMEM;
    }
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);

  return rc;
}
#endif

/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.







>
|







 







|
>
|
|
|
|
|
>




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







251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
** schema change has occurred.  That detail is handled by the
** outer sqlite3_step() wrapper procedure.
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }

  /* Assert that malloc() has not failed */
  db = p->db;
  assert( !db->mallocFailed );

................................................................................
/*
** This is the top-level implementation of sqlite3_step().  Call
** sqlite3Step() to do most of the work.  If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
#ifdef SQLITE_OMIT_PARSER
int sqlite3_step(sqlite3_stmt *pStmt){
  int rc = SQLITE_MISUSE;
  if( pStmt ){
    Vdbe *v;
    v = (Vdbe*)pStmt;
    sqlite3_mutex_enter(v->db->mutex);
    rc = sqlite3Step(v);
    sqlite3_mutex_leave(v->db->mutex);
  }
  return rc;
}
#else
int sqlite3_step(sqlite3_stmt *pStmt){
  int rc = SQLITE_MISUSE;
  if( pStmt ){
    int cnt = 0;

    Vdbe *v = (Vdbe*)pStmt;
    sqlite3 *db = v->db;
    sqlite3_mutex_enter(db->mutex);
    while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
           && cnt++ < 5
           && sqlite3Reprepare(v) ){
      sqlite3_reset(pStmt);
      v->expired = 0;
    }
    if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){
      /* This case occurs after failing to recompile an sql statement. 
      ** The error message from the SQL compiler has already been loaded 
      ** into the database handle. This block copies the error message 
      ** from the database handle into the statement and sets the statement
      ** program counter to 0 to ensure that when the statement is 
      ** finalized or reset the parser error message is available via
      ** sqlite3_errmsg() and sqlite3_errcode().
      */
      const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
      sqlite3_free(v->zErrMsg);
      if( !db->mallocFailed ){
        v->zErrMsg = sqlite3DbStrDup(db, zErr);
      } else {
        v->zErrMsg = 0;
        v->rc = SQLITE_NOMEM;
      }
    }
    rc = sqlite3ApiExit(db, rc);
    sqlite3_mutex_leave(db->mutex);
  }
  return rc;
}
#endif

/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.