]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure there is no ephemeral data on the stack before returning from
authordrh <drh@noemail.net>
Sat, 7 Jan 2006 18:10:32 +0000 (18:10 +0000)
committerdrh <drh@noemail.net>
Sat, 7 Jan 2006 18:10:32 +0000 (18:10 +0000)
an sqlite3_step() call.  Otherwise, if the statement is in READ UNCOMMITTED
mode then the data might be deleted or changed out from under us. (CVS 2884)

FossilOrigin-Name: 19f71a6d1982e986f5436bff71ef38b1bcc2e11d

manifest
manifest.uuid
src/vdbe.c

index 28598eff2e3be263d7fbab82c52b204abe4760d0..611e69fa3c4474d50d6d47117dcc0a399f1dccce 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enable\sredefinable\sI/O\sif\sthe\sSQLITE_ENABLE_REDEF_IO\smacro\sexists.\s(CVS\s2883)
-D 2006-01-07T16:06:07
+C Make\ssure\sthere\sis\sno\sephemeral\sdata\son\sthe\sstack\sbefore\sreturning\sfrom\nan\ssqlite3_step()\scall.\s\sOtherwise,\sif\sthe\sstatement\sis\sin\sREAD\sUNCOMMITTED\nmode\sthen\sthe\sdata\smight\sbe\sdeleted\sor\schanged\sout\sfrom\sunder\sus.\s(CVS\s2884)
+D 2006-01-07T18:10:33
 F Makefile.in c79fbdaa264c6afcd435f2fb492551de5a8cf80d
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -84,7 +84,7 @@ F src/update.c 29ba0385c8639803cd8e6e616e99096a0bc10443
 F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
 F src/util.c 8a3ef3c1b345cdadcee33ce4537c63bb0fda0ed8
 F src/vacuum.c a7301804d4f849da0ce9d869219c71c6d621c34e
-F src/vdbe.c 9ff36ae7887ba918e7c319729038eab59cfeb2b9
+F src/vdbe.c b0617790673c64b78740b7c1fc9c3e247e05612a
 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
 F src/vdbeInt.h 9b78ba00cc006bff17e04a54ba3ded9fc7810a10
 F src/vdbeapi.c 7335569b1bad946ba53892384b4b1534e877b1ee
@@ -335,7 +335,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 6593199a4d0d0e1f9cc2f48d30327b1c03a8170e
-R dca0e78f8894e9c4b7522be7f86ed95c
+P e170e15766389e978991b42a0d2ec303162aaad6
+R baaa14f4d07ba64e66d20e1ee1f3ee46
 U drh
-Z faf501161ea4c7faed845a75b2858bde
+Z 6a48941c0b9363c7694c0db132553ba2
index 77e0e8533fe92f7d9d458bb73af4361b25146bbe..9a8253a0a058bbbbdbccbd0bfd86b6fba0b8543e 100644 (file)
@@ -1 +1 @@
-e170e15766389e978991b42a0d2ec303162aaad6
\ No newline at end of file
+19f71a6d1982e986f5436bff71ef38b1bcc2e11d
\ No newline at end of file
index bf5ac0991bab362469f9e8217c8e690856803d50..ec113e434e22af6240e716720c6db7fde099221c 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.514 2006/01/07 13:21:04 danielk1977 Exp $
+** $Id: vdbe.c,v 1.515 2006/01/07 18:10:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -855,20 +855,42 @@ case OP_Push: {            /* no-push */
 
 /* Opcode: Callback P1 * *
 **
-** Pop P1 values off the stack and form them into an array.  Then
-** invoke the callback function using the newly formed array as the
-** 3rd parameter.
+** The top P1 values on the stack represent a single result row from
+** a query.  This opcode causes the sqlite3_step() call to terminate
+** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
+** structure to provide access to the top P1 values as the result
+** row.  When the sqlite3_step() function is run again, the top P1
+** values will be automatically popped from the stack before the next
+** instruction executes.
 */
 case OP_Callback: {            /* no-push */
-  int i;
+  Mem *pMem;
+  Mem *pFirstColumn;
   assert( p->nResColumn==pOp->p1 );
 
-  for(i=0; i<pOp->p1; i++){
-    Mem *pVal = &pTos[0-i];
-    sqlite3VdbeMemNulTerminate(pVal);
-    storeTypeInfo(pVal, db->enc);
+  /* Data in the pager might be moved or changed out from under us
+  ** in between the return from this sqlite3_step() call and the
+  ** next call to sqlite3_step().  So deephermeralize everything on 
+  ** the stack.  Note that ephemeral data is never stored in memory 
+  ** cells so we do not have to worry about them.
+  */
+  pFirstColumn = &pTos[0-pOp->p1];
+  for(pMem = p->aStack; pMem<pFirstColumn; pMem++){
+    Deephemeralize(pMem);
   }
 
+  /* Make sure the results of the current row are \000 terminated
+  ** and have an assigned type.  The results are deephemeralized as
+  ** as side effect.
+  */
+  for(; pMem<=pTos; pMem++ ){
+    sqlite3VdbeMemNulTerminate(pMem);
+    storeTypeInfo(pMem, db->enc);
+  }
+
+  /* Set up the statement structure so that it will pop the current
+  ** results from the stack when the statement returns.
+  */
   p->resOnStack = 1;
   p->nCallback++;
   p->popStack = pOp->p1;