aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/auth.c4
-rw-r--r--src/main.c128
-rw-r--r--src/table.c1
-rw-r--r--src/test1.c110
-rw-r--r--src/util.c26
-rw-r--r--src/vdbeaux.c4
6 files changed, 179 insertions, 94 deletions
diff --git a/src/auth.c b/src/auth.c
index 25f8f41d8..17f1df9bb 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -14,7 +14,7 @@
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
-** $Id: auth.c,v 1.18 2004/09/09 13:55:50 drh Exp $
+** $Id: auth.c,v 1.19 2004/09/30 13:43:13 drh Exp $
*/
#include "sqliteInt.h"
@@ -87,7 +87,7 @@ static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
"authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
"or SQLITE_DENY", rc);
- pParse->rc = SQLITE_MISUSE;
+ pParse->rc = SQLITE_ERROR;
}
/*
diff --git a/src/main.c b/src/main.c
index 2b8fe682a..4303ce91a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.261 2004/09/25 14:39:18 drh Exp $
+** $Id: main.c,v 1.262 2004/09/30 13:43:13 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -445,11 +445,7 @@ int sqlite3_close(sqlite3 *db){
if( !db ){
return SQLITE_OK;
}
-
- if( db->magic!=SQLITE_MAGIC_CLOSED &&
- db->magic!=SQLITE_MAGIC_OPEN &&
- db->magic!=SQLITE_MAGIC_BUSY
- ){
+ if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
@@ -530,6 +526,8 @@ void sqlite3RollbackAll(sqlite3 *db){
const char *sqlite3ErrStr(int rc){
const char *z;
switch( rc ){
+ case SQLITE_ROW:
+ case SQLITE_DONE:
case SQLITE_OK: z = "not an error"; break;
case SQLITE_ERROR: z = "SQL logic error or missing database"; break;
case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break;
@@ -613,6 +611,9 @@ int sqlite3_busy_handler(
int (*xBusy)(void*,int),
void *pArg
){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
return SQLITE_OK;
@@ -630,14 +631,16 @@ void sqlite3_progress_handler(
int (*xProgress)(void*),
void *pArg
){
- if( nOps>0 ){
- db->xProgress = xProgress;
- db->nProgressOps = nOps;
- db->pProgressArg = pArg;
- }else{
- db->xProgress = 0;
- db->nProgressOps = 0;
- db->pProgressArg = 0;
+ if( !sqlite3SafetyCheck(db) ){
+ if( nOps>0 ){
+ db->xProgress = xProgress;
+ db->nProgressOps = nOps;
+ db->pProgressArg = pArg;
+ }else{
+ db->xProgress = 0;
+ db->nProgressOps = 0;
+ db->pProgressArg = 0;
+ }
}
}
#endif
@@ -660,7 +663,9 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
** Cause any pending operation to stop at its earliest opportunity.
*/
void sqlite3_interrupt(sqlite3 *db){
- db->flags |= SQLITE_Interrupt;
+ if( !sqlite3SafetyCheck(db) ){
+ db->flags |= SQLITE_Interrupt;
+ }
}
/*
@@ -689,7 +694,10 @@ int sqlite3_create_function(
FuncDef *p;
int nName;
- if( (db==0 || zFunctionName==0 || sqlite3SafetyCheck(db)) ||
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ if( zFunctionName==0 ||
(xFunc && (xFinal || xStep)) ||
(!xFunc && (xFinal && !xStep)) ||
(!xFunc && (!xFinal && xStep)) ||
@@ -738,8 +746,12 @@ int sqlite3_create_function16(
){
int rc;
char const *zFunc8;
+ sqlite3_value *pTmp;
- sqlite3_value *pTmp = sqlite3GetTransientValue(db);
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ pTmp = sqlite3GetTransientValue(db);
sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
@@ -854,22 +866,18 @@ int sqlite3BtreeFactory(
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
- if( !db || !db->pErr ){
- /* If db is NULL, then assume that a malloc() failed during an
- ** sqlite3_open() call.
- */
+ const char *z;
+ if( sqlite3_malloc_failed ){
return sqlite3ErrStr(SQLITE_NOMEM);
}
- if( db->magic!=SQLITE_MAGIC_OPEN &&
- db->magic!=SQLITE_MAGIC_BUSY &&
- db->magic!=SQLITE_MAGIC_CLOSED
- ){
+ if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
return sqlite3ErrStr(SQLITE_MISUSE);
}
- if( !sqlite3_value_text(db->pErr) ){
- return sqlite3ErrStr(db->errCode);
+ z = sqlite3_value_text(db->pErr);
+ if( z==0 ){
+ z = sqlite3ErrStr(db->errCode);
}
- return sqlite3_value_text(db->pErr);
+ return z;
}
/*
@@ -896,31 +904,32 @@ const void *sqlite3_errmsg16(sqlite3 *db){
0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
};
- if( db && db->pErr ){
- if( db->magic!=SQLITE_MAGIC_OPEN &&
- db->magic!=SQLITE_MAGIC_BUSY &&
- db->magic!=SQLITE_MAGIC_CLOSED
- ){
- return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
- }
- if( !sqlite3_value_text16(db->pErr) ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
- }
- if( sqlite3_value_text16(db->pErr) ){
- return sqlite3_value_text16(db->pErr);
- }
- }
-
- /* If db is NULL, then assume that a malloc() failed during an
- ** sqlite3_open() call. We have a static version of the string
- ** "out of memory" encoded using UTF-16 just for this purpose.
- */
- return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ const void *z;
+ if( sqlite3_malloc_failed ){
+ return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ }
+ if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
+ return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ }
+ z = sqlite3_value_text16(db->pErr);
+ if( z==0 ){
+ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
+ SQLITE_UTF8, SQLITE_STATIC);
+ z = sqlite3_value_text16(db->pErr);
+ }
+ return z;
}
+/*
+** Return the most recent error code generated by an SQLite routine.
+*/
int sqlite3_errcode(sqlite3 *db){
- if( !db ) return SQLITE_NOMEM;
+ if( sqlite3_malloc_failed ){
+ return SQLITE_NOMEM;
+ }
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
return db->errCode;
}
@@ -1043,6 +1052,9 @@ int sqlite3_prepare16(
int rc;
sqlite3_value *pTmp;
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
pTmp = sqlite3GetTransientValue(db);
sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
@@ -1245,6 +1257,10 @@ int sqlite3_create_collation(
CollSeq *pColl;
int rc = SQLITE_OK;
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
@@ -1283,7 +1299,11 @@ int sqlite3_create_collation16(
int(*xCompare)(void*,int,const void*,int,const void*)
){
char const *zName8;
- sqlite3_value *pTmp = sqlite3GetTransientValue(db);
+ sqlite3_value *pTmp;
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ pTmp = sqlite3GetTransientValue(db);
sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
@@ -1298,6 +1318,9 @@ int sqlite3_collation_needed(
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
db->pCollNeededArg = pCollNeededArg;
@@ -1313,6 +1336,9 @@ int sqlite3_collation_needed16(
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
db->xCollNeeded = 0;
db->xCollNeeded16 = xCollNeeded16;
db->pCollNeededArg = pCollNeededArg;
diff --git a/src/table.c b/src/table.c
index e35ca345c..d4ef2c8a7 100644
--- a/src/table.c
+++ b/src/table.c
@@ -154,6 +154,7 @@ int sqlite3_get_table(
}
sqliteFree(res.zErrMsg);
}
+ db->errCode = res.rc;
return res.rc;
}
sqliteFree(res.zErrMsg);
diff --git a/src/test1.c b/src/test1.c
index 70c2482f7..77230b8c9 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.103 2004/09/08 20:13:05 drh Exp $
+** $Id: test1.c,v 1.104 2004/09/30 13:43:13 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -52,13 +52,36 @@ static const char * errorName(int rc){
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
- case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
+ case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
default: zName = "SQLITE_Unknown"; break;
}
return zName;
}
/*
+** Convert an sqlite3_stmt* into an sqlite3*. This depends on the
+** fact that the sqlite3* is the first field in the Vdbe structure.
+*/
+#define StmtToDb(X) (*(sqlite3**)(X))
+
+/*
+** Check a return value to make sure it agrees with the results
+** from sqlite3_errcode.
+*/
+int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
+ if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){
+ char zBuf[200];
+ int r2 = sqlite3_errcode(db);
+ sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
+ errorName(rc), rc, errorName(r2), r2);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, zBuf, 0);
+ return 1;
+ }
+ return 0;
+}
+
+/*
** Decode a pointer to an sqlite3 object.
*/
static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
@@ -160,6 +183,7 @@ static int test_exec_printf(
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
Tcl_DStringFree(&str);
if( zErr ) free(zErr);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -234,6 +258,7 @@ static int test_get_table_printf(
}
sqlite3_free_table(aResult);
if( zErr ) free(zErr);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -451,6 +476,7 @@ static int test_create_function(
int argc, /* Number of arguments */
char **argv /* Text of each argument */
){
+ int rc;
sqlite3 *db;
sqlite3_value *pVal;
extern void Md5_Register(sqlite3*);
@@ -461,16 +487,20 @@ static int test_create_function(
return TCL_ERROR;
}
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
- sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0,
- ifnullFunc, 0, 0);
+ rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0,
+ ifnullFunc, 0, 0);
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
** because it is not tested anywhere else. */
- pVal = sqlite3ValueNew();
- sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
- sqlite3_create_function16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
- 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
- sqlite3ValueFree(pVal);
+ if( rc==SQLITE_OK ){
+ pVal = sqlite3ValueNew();
+ sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
+ rc = sqlite3_create_function16(db,
+ sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
+ 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
+ sqlite3ValueFree(pVal);
+ }
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -512,16 +542,20 @@ static int test_create_aggregate(
char **argv /* Text of each argument */
){
sqlite3 *db;
+ int rc;
if( argc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" FILENAME\"", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
- sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
- countStep,countFinalize);
- sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
+ rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
countStep,countFinalize);
+ if( rc==SQLITE_OK ){
+ sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
+ countStep,countFinalize);
+ }
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -831,6 +865,7 @@ static int test_register_func(
Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
return TCL_ERROR;
}
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -847,6 +882,7 @@ static int test_finalize(
){
sqlite3_stmt *pStmt;
int rc;
+ sqlite3 *db;
if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -856,8 +892,10 @@ static int test_finalize(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ db = StmtToDb(pStmt);
rc = sqlite3_finalize(pStmt);
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
}
@@ -884,6 +922,7 @@ static int test_reset(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
rc = sqlite3_reset(pStmt);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc ){
return TCL_ERROR;
}
@@ -956,6 +995,7 @@ static int test_bind(
"\"null\" or \"static\" or \"normal\"", 0);
return TCL_ERROR;
}
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc ){
char zBuf[50];
sprintf(zBuf, "(%d) ", rc);
@@ -1045,25 +1085,28 @@ static int test_collate(
sqlite3 *db;
int val;
sqlite3_value *pVal;
+ int rc;
if( objc!=5 ) goto bad_args;
pTestCollateInterp = interp;
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
- sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
- (void *)SQLITE_UTF8, val?test_collate_func:0);
- if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
- sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
- (void *)SQLITE_UTF16LE, val?test_collate_func:0);
- if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
+ rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
+ (void *)SQLITE_UTF8, val?test_collate_func:0);
+ if( rc==SQLITE_OK ){
+ if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
+ rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
+ (void *)SQLITE_UTF16LE, val?test_collate_func:0);
+ if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
- pVal = sqlite3ValueNew();
- sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
- sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
- SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
- sqlite3ValueFree(pVal);
-
+ pVal = sqlite3ValueNew();
+ sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
+ SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
+ sqlite3ValueFree(pVal);
+ }
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
bad_args:
@@ -1093,10 +1136,12 @@ static int test_collate_needed(
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
+ int rc;
if( objc!=2 ) goto bad_args;
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
- sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
+ rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
bad_args:
@@ -1335,6 +1380,7 @@ static int test_bind_int(
if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
rc = sqlite3_bind_int(pStmt, idx, value);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1372,6 +1418,7 @@ static int test_bind_int64(
if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
rc = sqlite3_bind_int64(pStmt, idx, value);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1409,6 +1456,7 @@ static int test_bind_double(
if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR;
rc = sqlite3_bind_double(pStmt, idx, value);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1443,6 +1491,7 @@ static int test_bind_null(
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
rc = sqlite3_bind_null(pStmt, idx);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1482,6 +1531,7 @@ static int test_bind_text(
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1521,6 +1571,7 @@ static int test_bind_text16(
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1559,6 +1610,7 @@ static int test_bind_blob(
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
@@ -1757,6 +1809,7 @@ static int test_prepare(
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
if( zTail ){
if( bytes>=0 ){
bytes = bytes - (zTail-zSql);
@@ -1796,7 +1849,8 @@ static int test_prepare16(
const void *zTail = 0;
Tcl_Obj *pTail = 0;
sqlite3_stmt *pStmt = 0;
- char zBuf[50];
+ char zBuf[50];
+ int rc;
int bytes; /* The integer specified as arg 3 */
int objlen; /* The byte-array length of arg 2 */
@@ -1809,7 +1863,9 @@ static int test_prepare16(
zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
- if( SQLITE_OK!=sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail) ){
+ rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail);
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+ if( rc ){
return TCL_ERROR;
}
diff --git a/src/util.c b/src/util.c
index 6f284d1f4..5b031e843 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.118 2004/09/25 14:39:19 drh Exp $
+** $Id: util.c,v 1.119 2004/09/30 13:43:13 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -746,19 +746,21 @@ int sqlite3SafetyOff(sqlite3 *db){
}
/*
-** Check to make sure we are not currently executing an sqlite3_exec().
-** If we are currently in an sqlite3_exec(), return true and set
-** sqlite.magic to SQLITE_MAGIC_ERROR. This will cause a complete
-** shutdown of the database.
-**
-** This routine is used to try to detect when API routines are called
-** at the wrong time or in the wrong sequence.
+** Check to make sure we have a valid db pointer. This test is not
+** foolproof but it does provide some measure of protection against
+** misuse of the interface such as passing in db pointers that are
+** NULL or which have been previously closed. If this routine returns
+** TRUE it means that the db pointer is invalid and should not be
+** dereferenced for any reason. The calling function should invoke
+** SQLITE_MISUSE immediately.
*/
int sqlite3SafetyCheck(sqlite3 *db){
- if( db->pVdbe!=0 ){
- db->magic = SQLITE_MAGIC_ERROR;
- return 1;
- }
+ int magic;
+ if( db==0 ) return 1;
+ magic = db->magic;
+ if( magic!=SQLITE_MAGIC_CLOSED &&
+ magic!=SQLITE_MAGIC_OPEN &&
+ magic!=SQLITE_MAGIC_BUSY ) return 1;
return 0;
}
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 286ca8423..e7cadea88 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1274,7 +1274,7 @@ int sqlite3VdbeHalt(Vdbe *p){
*/
int sqlite3VdbeReset(Vdbe *p){
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0);
+ sqlite3Error(p->db, SQLITE_MISUSE, 0);
return SQLITE_MISUSE;
}
@@ -1288,7 +1288,7 @@ int sqlite3VdbeReset(Vdbe *p){
** main database structure.
*/
if( p->zErrMsg ){
- sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0);
+ sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
sqliteFree(p->zErrMsg);
p->zErrMsg = 0;
}else if( p->rc ){