1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

In sqlite3_bind() interfaces, avoid acquiring the mutex until after the

statement handle has been validated.  Ticket #3418. (CVS 5768)

FossilOrigin-Name: 693503e241001271512f4ce3e8cc932ba6a3106c
This commit is contained in:
drh
2008-10-06 12:46:43 +00:00
parent de89c4cc17
commit 488e7b6323
3 changed files with 36 additions and 34 deletions

View File

@@ -13,7 +13,7 @@
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.141 2008/09/04 12:03:43 shane Exp $
** $Id: vdbeapi.c,v 1.142 2008/10/06 12:46:44 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
@@ -1005,17 +1005,24 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** A successful evaluation of this routine acquires the mutex on p.
** the mutex is released if any kind of error occurs.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
Mem *pVar;
if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
if( p ) sqlite3Error(p->db, SQLITE_MISUSE, 0);
if( p==0 ) return SQLITE_MISUSE;
sqlite3_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
sqlite3Error(p->db, SQLITE_MISUSE, 0);
sqlite3_mutex_leave(p->db->mutex);
return SQLITE_MISUSE;
}
if( i<1 || i>p->nVar ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
sqlite3_mutex_leave(p->db->mutex);
return SQLITE_RANGE;
}
i--;
@@ -1041,21 +1048,19 @@ static int bindText(
Mem *pVar;
int rc;
if( p==0 ){
return SQLITE_MISUSE;
}
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK && zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
if( rc==SQLITE_OK ){
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
sqlite3Error(p->db, rc, 0);
rc = sqlite3ApiExit(p->db, rc);
}
sqlite3Error(p->db, rc, 0);
rc = sqlite3ApiExit(p->db, rc);
sqlite3_mutex_leave(p->db->mutex);
}
sqlite3_mutex_leave(p->db->mutex);
return rc;
}
@@ -1075,12 +1080,11 @@ int sqlite3_bind_blob(
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
sqlite3_mutex_leave(p->db->mutex);
}
sqlite3_mutex_leave(p->db->mutex);
return rc;
}
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
@@ -1089,20 +1093,20 @@ int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
sqlite3_mutex_leave(p->db->mutex);
}
sqlite3_mutex_leave(p->db->mutex);
return rc;
}
int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
sqlite3_mutex_leave(p->db->mutex);
if( rc==SQLITE_OK ){
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
}
int sqlite3_bind_text(
@@ -1128,27 +1132,25 @@ int sqlite3_bind_text16(
int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
if( rc==SQLITE_OK ){
rc = sqlite3VdbeChangeEncoding(&p->aVar[i-1], ENC(p->db));
}
sqlite3_mutex_leave(p->db->mutex);
}
rc = sqlite3ApiExit(p->db, rc);
sqlite3_mutex_leave(p->db->mutex);
/* rc = sqlite3ApiExit(p->db, rc); */
return rc;
}
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
sqlite3_mutex_leave(p->db->mutex);
}
sqlite3_mutex_leave(p->db->mutex);
return rc;
}