diff options
author | drh <drh@noemail.net> | 2004-09-30 13:43:13 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2004-09-30 13:43:13 +0000 |
commit | c60d04464fe6269a11a5b50ee29629d3faf4b03a (patch) | |
tree | 1582b7d75ebbd8df031381dcf0a846d44c3c3d57 /src | |
parent | 44f87bdc564c403faf6e772a1d70b3b6cedcb64e (diff) | |
download | sqlite-c60d04464fe6269a11a5b50ee29629d3faf4b03a.tar.gz sqlite-c60d04464fe6269a11a5b50ee29629d3faf4b03a.zip |
Allow functions to be created when there are outstanding VMs.
(Ticket #926) Fix problems with sqlite3_errcode(). Add tests for
sqlite3_errcode(). (CVS 1989)
FossilOrigin-Name: d0f1dc5898382258b283308c2cce55a8bc378ee4
Diffstat (limited to 'src')
-rw-r--r-- | src/auth.c | 4 | ||||
-rw-r--r-- | src/main.c | 128 | ||||
-rw-r--r-- | src/table.c | 1 | ||||
-rw-r--r-- | src/test1.c | 110 | ||||
-rw-r--r-- | src/util.c | 26 | ||||
-rw-r--r-- | src/vdbeaux.c | 4 |
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 ){ |