Add check to prevent a VList from growing after pointers to labels have been
taken.

FossilOrigin-Name: aa23d7eaf69f5ecbf9500b2353846094cae41e6c
diff --git a/manifest b/manifest
index ed40e8d..6842b9b 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sVList\sobject\sso\sthat\sit\sactually\sworks.
-D 2016-12-23T13:30:53.667
+C Add\scheck\sto\sprevent\sa\sVList\sfrom\sgrowing\safter\spointers\sto\slabels\shave\sbeen\ntaken.
+D 2016-12-23T13:52:45.010
 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
@@ -341,7 +341,7 @@
 F src/date.c b48378aeac68fa20c811404955a9b62108df47d8
 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
 F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5
-F src/expr.c fedcfcd8749f95627dfe0aeb5630b68c5979cb0b
+F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
 F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a
@@ -453,7 +453,7 @@
 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8
 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
-F src/util.c adf5ff9e457b69d3cab2afa45c9c4ce5da83da06
+F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9
 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
 F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171
 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c
@@ -1539,7 +1539,7 @@
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 68ecafa1425a41358c88f41efea3262f1b4490f2
-R e3b464298f4645ba05beea0d35779569
+P 9dcd85698af46fd5ba34004ca690d368c4ae3078
+R 2f816100f2d74d42d3a1978c26f09af2
 U drh
-Z e1b50397ad009309edd4038594b0291c
+Z 3cd0270ead5747022cdd1e84b75d8956
diff --git a/manifest.uuid b/manifest.uuid
index d87d18b..63d4ce3 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-9dcd85698af46fd5ba34004ca690d368c4ae3078
\ No newline at end of file
+aa23d7eaf69f5ecbf9500b2353846094cae41e6c
\ No newline at end of file
diff --git a/src/expr.c b/src/expr.c
index 3f8406b..ecc6c79 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3422,6 +3422,7 @@
       if( pExpr->u.zToken[1]!=0 ){
         const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
         assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
+        pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
         sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
       }
       return target;
diff --git a/src/util.c b/src/util.c
index 5ece922..b9684c6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1457,7 +1457,7 @@
 /*
 ** Add a new name/number pair to a VList.  This might require that the
 ** VList object be reallocated, so return the new VList.  If an OOM
-** error occurs, the original VList freed, NULL is returned, and the
+** error occurs, the original VList returned and the
 ** db->mallocFailed flag is set.
 **
 ** A VList is really just an array of integers.  To destroy a VList,
@@ -1468,11 +1468,27 @@
 ** Each name/number pair is encoded by subsequent groups of 3 or more
 ** integers.
 **
-** Each name/number pair starts with two integers which are the number
+** Each name/number pair starts with two integers which are the numeric
 ** value for the pair and the size of the name/number pair, respectively.
 ** The text name overlays one or more following integers.  The text name
 ** is always zero-terminated.
-** 
+**
+** Conceptually:
+**
+**    struct VList {
+**      int nAlloc;   // Number of allocated slots 
+**      int nUsed;    // Number of used slots 
+**      struct VListEntry {
+**        int iValue;    // Value for this entry
+**        int nSlot;     // Slots used by this entry
+**        // ... variable name goes here
+**      } a[0];
+**    }
+**
+** During code generation, pointers to the variable names within the
+** VList are taken.  When that happens, nAlloc is set to zero as an 
+** indication that the VList may never again be enlarged, since the
+** accompanying realloc() would invalidate the pointers.
 */
 VList *sqlite3VListAdd(
   sqlite3 *db,           /* The database connection used for malloc() */
@@ -1482,18 +1498,16 @@
   int iVal               /* Value to associate with zName */
 ){
   int nInt;              /* number of sizeof(int) objects needed for zName */
-  char *z;
-  int i;
+  char *z;               /* Pointer to where zName will be stored */
+  int i;                 /* Index in pIn[] where zName is stored */
 
   nInt = nName/4 + 3;
+  assert( pIn==0 || pIn[0]>=3 );  /* Verify ok to add new elements */
   if( pIn==0 || pIn[1]+nInt > pIn[0] ){
     /* Enlarge the allocation */
     int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
     VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
-    if( pOut==0 ){
-      sqlite3DbFree(db, pIn);
-      return 0;
-    }
+    if( pOut==0 ) return pIn;
     if( pIn==0 ) pOut[1] = 2;
     pIn = pOut;
     pIn[0] = nAlloc;