/ Check-in [ee1382a3]
Login

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

Overview
Comment:Fix a potential null-pointer dereference and crash in the case where one thread is calling sqlite3_column_text() and another thread is calling sqlite3_step() on the same prepared statement at the same instant.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ee1382a36303eff8d94275ac3b12e5ce398ee620
User & Date: drh 2016-09-22 21:37:18
Context
2016-09-23
18:13
New test case for the ORDER BY LIMIT optimization. check-in: 9a5a489d user: drh tags: trunk
2016-09-22
21:37
Fix a potential null-pointer dereference and crash in the case where one thread is calling sqlite3_column_text() and another thread is calling sqlite3_step() on the same prepared statement at the same instant. check-in: ee1382a3 user: drh tags: trunk
18:53
Remove the internal sqlite3CodeOnce() interface, replacing it with a direct call to sqlite3VdbeAddOp0(v,OP_Once). Slightly smaller and faster. check-in: c3774c6a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeapi.c.

948
949
950
951
952
953
954
955

956

957
958
959
960
961
962
963
964
965
966
967
968
969
...
988
989
990
991
992
993
994


995
996
997
998
999
1000
1001
** of NULL.
*/
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
  Vdbe *pVm;
  Mem *pOut;

  pVm = (Vdbe *)pStmt;
  if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){

    sqlite3_mutex_enter(pVm->db->mutex);

    pOut = &pVm->pResultSet[i];
  }else{
    if( pVm && ALWAYS(pVm->db) ){
      sqlite3_mutex_enter(pVm->db->mutex);
      sqlite3Error(pVm->db, SQLITE_RANGE);
    }
    pOut = (Mem*)columnNullValue();
  }
  return pOut;
}

/*
** This function is called after invoking an sqlite3_value_XXX function on a 
................................................................................
  /* If malloc() failed during an encoding conversion within an
  ** sqlite3_column_XXX API, then set the return code of the statement to
  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
  ** and _finalize() will return NOMEM.
  */
  Vdbe *p = (Vdbe *)pStmt;
  if( p ){


    p->rc = sqlite3ApiExit(p->db, p->rc);
    sqlite3_mutex_leave(p->db->mutex);
  }
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row







|
>
|
>


<
<
|
<







 







>
>







948
949
950
951
952
953
954
955
956
957
958
959
960


961

962
963
964
965
966
967
968
...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
** of NULL.
*/
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
  Vdbe *pVm;
  Mem *pOut;

  pVm = (Vdbe *)pStmt;
  if( pVm==0 ) return (Mem*)columnNullValue();
  assert( pVm->db );
  sqlite3_mutex_enter(pVm->db->mutex);
  if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
    pOut = &pVm->pResultSet[i];
  }else{


    sqlite3Error(pVm->db, SQLITE_RANGE);

    pOut = (Mem*)columnNullValue();
  }
  return pOut;
}

/*
** This function is called after invoking an sqlite3_value_XXX function on a 
................................................................................
  /* If malloc() failed during an encoding conversion within an
  ** sqlite3_column_XXX API, then set the return code of the statement to
  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
  ** and _finalize() will return NOMEM.
  */
  Vdbe *p = (Vdbe *)pStmt;
  if( p ){
    assert( p->db!=0 );
    assert( sqlite3_mutex_held(p->db->mutex) );
    p->rc = sqlite3ApiExit(p->db, p->rc);
    sqlite3_mutex_leave(p->db->mutex);
  }
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row