aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2009-04-02 18:32:26 +0000
committerdrh <drh@noemail.net>2009-04-02 18:32:26 +0000
commit860e077a7aa6c5aa36de9ed6117016c92f9464f0 (patch)
tree9866aff2593a8922d8555ad4478ccb752db2db68 /src
parentfa542f1fc80c7c27012b427da9a098eb20f629d6 (diff)
downloadsqlite-860e077a7aa6c5aa36de9ed6117016c92f9464f0.tar.gz
sqlite-860e077a7aa6c5aa36de9ed6117016c92f9464f0.zip
Fix the sqlite3_prepare() family of interfaces so that they zero the *ppStmt
value even on an SQLITE_MISUSE return. Make it clear in the documentation that the ppStmt parameter cannot be zero. (CVS 6441) FossilOrigin-Name: 23bf9f266559603e37b2703715eaf8ef5af6bb17
Diffstat (limited to 'src')
-rw-r--r--src/prepare.c12
-rw-r--r--src/sqlite.h.in16
-rw-r--r--src/test9.c19
3 files changed, 29 insertions, 18 deletions
diff --git a/src/prepare.c b/src/prepare.c
index c4d88a3be..e3479f3b8 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.115 2009/04/01 16:33:38 drh Exp $
+** $Id: prepare.c,v 1.116 2009/04/02 18:32:27 drh Exp $
*/
#include "sqliteInt.h"
@@ -528,11 +528,8 @@ static int sqlite3Prepare(
int rc = SQLITE_OK;
int i;
- assert( ppStmt );
- *ppStmt = 0;
- if( sqlite3SafetyOn(db) ){
- return SQLITE_MISUSE;
- }
+ if( sqlite3SafetyOn(db) ) return SQLITE_MISUSE;
+ assert( ppStmt && *ppStmt==0 );
assert( !db->mallocFailed );
assert( sqlite3_mutex_held(db->mutex) );
@@ -671,6 +668,8 @@ static int sqlite3LockAndPrepare(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
+ assert( ppStmt!=0 );
+ *ppStmt = 0;
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE;
}
@@ -773,6 +772,7 @@ static int sqlite3Prepare16(
const char *zTail8 = 0;
int rc = SQLITE_OK;
+ assert( ppStmt );
*ppStmt = 0;
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE;
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index d8f51e79c..1ecd14c23 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
-** @(#) $Id: sqlite.h.in,v 1.436 2009/03/20 13:15:30 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.437 2009/04/02 18:32:27 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -2229,7 +2229,8 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
-** prior call to [sqlite3_open()], [sqlite3_open_v2()] or [sqlite3_open16()].
+** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
+** [sqlite3_open16()]. The database connection must not have been closed.
**
** The second argument, "zSql", is the statement to be compiled, encoded
** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
@@ -2246,17 +2247,18 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** is equal to the number of bytes in the input string <i>including</i>
** the nul-terminator bytes.
**
-** *pzTail is made to point to the first byte past the end of the
-** first SQL statement in zSql. These routines only compile the first
-** statement in zSql, so *pzTail is left pointing to what remains
-** uncompiled.
+** If pzTail is not NULL then *pzTail is made to point to the first byte
+** past the end of the first SQL statement in zSql. These routines only
+** compile the first statement in zSql, so *pzTail is left pointing to
+** what remains uncompiled.
**
** *ppStmt is left pointing to a compiled [prepared statement] that can be
** executed using [sqlite3_step()]. If there is an error, *ppStmt is set
** to NULL. If the input text contains no SQL (if the input is an empty
** string or a comment) then *ppStmt is set to NULL.
-** {A13018} The calling procedure is responsible for deleting the compiled
+** The calling procedure is responsible for deleting the compiled
** SQL statement using [sqlite3_finalize()] after it has finished with it.
+** ppStmt may not be NULL.
**
** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
**
diff --git a/src/test9.c b/src/test9.c
index 2043da23f..222bdc390 100644
--- a/src/test9.c
+++ b/src/test9.c
@@ -14,7 +14,7 @@
** for completeness. Test code is written in C for these cases
** as there is not much point in binding to Tcl.
**
-** $Id: test9.c,v 1.6 2008/07/11 13:53:55 drh Exp $
+** $Id: test9.c,v 1.7 2009/04/02 18:32:27 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -114,6 +114,7 @@ static int c_misuse_test(
){
const char *zErrFunction = "N/A";
sqlite3 *db = 0;
+ sqlite3_stmt *pStmt;
int rc;
if( objc!=1 ){
@@ -138,29 +139,37 @@ static int c_misuse_test(
goto error_out;
}
- rc = sqlite3_prepare(db, 0, 0, 0, 0);
+ pStmt = (sqlite3_stmt*)1234;
+ rc = sqlite3_prepare(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare";
goto error_out;
}
+ assert( pStmt==0 ); /* Verify that pStmt is zeroed even on a MISUSE error */
- rc = sqlite3_prepare_v2(db, 0, 0, 0, 0);
+ pStmt = (sqlite3_stmt*)1234;
+ rc = sqlite3_prepare_v2(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare_v2";
goto error_out;
}
+ assert( pStmt==0 );
#ifndef SQLITE_OMIT_UTF16
- rc = sqlite3_prepare16(db, 0, 0, 0, 0);
+ pStmt = (sqlite3_stmt*)1234;
+ rc = sqlite3_prepare16(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare16";
goto error_out;
}
- rc = sqlite3_prepare16_v2(db, 0, 0, 0, 0);
+ assert( pStmt==0 );
+ pStmt = (sqlite3_stmt*)1234;
+ rc = sqlite3_prepare16_v2(db, 0, 0, &pStmt, 0);
if( rc!=SQLITE_MISUSE ){
zErrFunction = "sqlite3_prepare16_v2";
goto error_out;
}
+ assert( pStmt==0 );
#endif
return TCL_OK;