]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Protect Tcl_Obj pointers from change using Tcl_IncrRefCount() while
authordrh <drh@noemail.net>
Thu, 26 Aug 2004 00:56:05 +0000 (00:56 +0000)
committerdrh <drh@noemail.net>
Thu, 26 Aug 2004 00:56:05 +0000 (00:56 +0000)
executing SQL statements in the TCL bindings. (CVS 1903)

FossilOrigin-Name: 6199f2f243514bbd4befbf768a7e03aec775bed2

manifest
manifest.uuid
src/tclsqlite.c

index e3dd1cdd591d2624d3b8485f157b96526466fa4f..fc1764e13dff25a896425e2d221b2b0854410d29 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Host\sparameter\snames\sconform\sto\sSQL-2003.\s(CVS\s1902)
-D 2004-08-25T04:07:02
+C Protect\sTcl_Obj\spointers\sfrom\schange\susing\sTcl_IncrRefCount()\swhile\nexecuting\sSQL\sstatements\sin\sthe\sTCL\sbindings.\s(CVS\s1903)
+D 2004-08-26T00:56:05
 F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -62,7 +62,7 @@ F src/shell.c 42f65424a948f197f389e13bc7aaa3cf24dafd0c
 F src/sqlite.h.in de2be4043f0bfa16958d33392a3e7a5e7d4bd50b
 F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
 F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
-F src/tclsqlite.c dbbcc553c78fbf928461fb951c7a59f05f46a212
+F src/tclsqlite.c b7dd8b3531b70188d03354db530de0f2ffcac697
 F src/test1.c b87fae63b2994c150a579c4101f302be48ad77bc
 F src/test2.c f4c2f3928f1998fd8cb75a81e33a60e025ea85d4
 F src/test3.c 94d0a2a90bccd85802488cb42c69ec8afd2e4646
@@ -243,7 +243,7 @@ F www/tclsqlite.tcl 06a86cba4d7fc88e2bcd633b57702d3d16abebb5
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 054dd8901dbfe64a8f61e7b99e23512057bad99a
-R d23910c2c69266eac96be9e2b599d41f
+P fd584d1ccf6643b723c2ff0a7a16c2aea3f1142c
+R c2945f067807301ea9f9b82dd56f837f
 U drh
-Z 5aba1f7ee7cf5f46b8a50edb359ed966
+Z 3e4b219d5ef080e3900472694ea85d39
index 24a4dde35d7424ad34de2ffb6d396ae36b110d6f..538c0bf9e708cc6517ea0dbf29bf153f2102f504 100644 (file)
@@ -1 +1 @@
-fd584d1ccf6643b723c2ff0a7a16c2aea3f1142c
\ No newline at end of file
+6199f2f243514bbd4befbf768a7e03aec775bed2
\ No newline at end of file
index 8388495c3962a106e8cbb922bcd6fcd80e008dd1..8c91ccd105713e37c43af158c929d8c5fe309b4d 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.102 2004/08/25 04:07:02 drh Exp $
+** $Id: tclsqlite.c,v 1.103 2004/08/26 00:56:05 drh Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -698,6 +698,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     sqlite3_stmt *pStmt;   /* Compiled SQL statment */
     Tcl_Obj *pArray;       /* Name of array into which results are written */
     Tcl_Obj *pScript;      /* Script to run for each result set */
+    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
+    int nParm;             /* Number of entries used in apParm[] */
+    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
 
     Tcl_Obj *pRet = Tcl_NewObj();
     Tcl_IncrRefCount(pRet);
@@ -717,6 +720,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       pScript = objv[4];
     }
 
+    Tcl_IncrRefCount(objv[2]);
     zSql = Tcl_GetStringFromObj(objv[2], 0);
     while( zSql[0] ){
       int i;      /* Loop counter */
@@ -741,8 +745,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
         }
       }
 
-      /* Bind values to wildcards that begin with $ */  
+      /* Bind values to wildcards that begin with $ or : */  
       nVar = sqlite3_bind_parameter_count(pStmt);
+      nParm = 0;
+      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
+        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
+      }else{
+        apParm = aParm;
+      }
       for(i=1; i<=nVar; i++){
         const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
         if( zVar[0]=='$' || zVar[0]==':' ){
@@ -755,6 +765,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
             if( c=='b' && strcmp(zType,"bytearray")==0 ){
               data = Tcl_GetByteArrayFromObj(pVar, &n);
               sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
+              Tcl_IncrRefCount(pVar);
+              apParm[nParm++] = pVar;
             }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
                   (c=='i' && strcmp(zType,"int")==0) ){
               Tcl_GetIntFromObj(interp, pVar, &n);
@@ -766,6 +778,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
             }else{
               data = Tcl_GetStringFromObj(pVar, &n);
               sqlite3_bind_text(pStmt, i, data, n, SQLITE_STATIC);
+              Tcl_IncrRefCount(pVar);
+              apParm[nParm++] = pVar;
             }
           }
         }
@@ -853,6 +867,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
         Tcl_Free((char*)apColName);
       }
 
+      /* Free the bound string and blob parameters */
+      for(i=0; i<nParm; i++){
+        Tcl_DecrRefCount(apParm[i]);
+      }
+      if( apParm!=aParm ){
+        Tcl_Free((char*)apParm);
+      }
+
       /* Finalize the statement.  If the result code is SQLITE_SCHEMA, then
       ** try again to execute the same statement
       */
@@ -868,6 +890,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
 
       zSql = zLeft;
     }
+    Tcl_DecrRefCount(objv[2]);
 
     if( rc==TCL_OK ){
       Tcl_SetObjResult(interp, pRet);