From 4305d10360ab7b6fba381b9e783e14503a513b58 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Jul 2003 12:34:12 +0000 Subject: [PATCH] The {quote: SrcList} object was not being expanded correctly by a call to sqliteSrcListAppend() if the {quote: SrcList} had previously been duplicated by a call to sqliteSrcListDup(). Ticket #416. This check-in fixes that problem by keeping a separate nAlloc field on {quote: SrcList}. A similar change is made to {quote: IdList} and {quote: ExprList} to avoid future problems. (CVS 1067) FossilOrigin-Name: da6273255471673841fdcadc688aeac80722e130 --- manifest | 20 ++++++------ manifest.uuid | 2 +- src/build.c | 14 ++++++--- src/expr.c | 15 ++++----- src/sqliteInt.h | 7 +++-- src/util.c | 82 +++++++++++++++++++++++++++++-------------------- test/misc2.test | 18 ++++++++++- 7 files changed, 98 insertions(+), 60 deletions(-) diff --git a/manifest b/manifest index 93d8d90723..65e7fbdc58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\screating\sa\snew\sjournal\sfile,\sopen\sa\s(read-only)\sfile\sdescriptor\son\sthe\ndirectory\scontaining\sthe\sjournal\sand\ssync\sthat\sdirectory\sonce\sto\smake\ssure\nthat\sthe\sjournal\sfilename\sentry\sgets\sinto\sthe\sdirectory.\s\sTicket\s#410.\s(CVS\s1066) -D 2003-07-27T18:59:43 +C The\s{quote:\sSrcList}\sobject\swas\snot\sbeing\sexpanded\scorrectly\sby\sa\scall\sto\r\nsqliteSrcListAppend()\sif\sthe\s{quote:\sSrcList}\shad\spreviously\sbeen\sduplicated\sby\r\na\scall\sto\ssqliteSrcListDup().\s\sTicket\s#416.\sThis\scheck-in\sfixes\sthat\sproblem\r\nby\skeeping\sa\sseparate\snAlloc\sfield\son\s{quote:\sSrcList}.\s\sA\ssimilar\schange\sis\smade\r\nto\s{quote:\sIdList}\sand\s{quote:\sExprList}\sto\savoid\sfuture\sproblems.\s(CVS\s1067) +D 2003-07-30T12:34:12 F Makefile.in 9ad23ed4ca97f9670c4496432e3fbd4b3760ebde F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -24,11 +24,11 @@ F src/auth.c c8f50d4507e37779d96ff3c55417bc2b612dfed6 F src/btree.c ba1cc0c71c3d2742b9a9047832335dc7d3656c45 F src/btree.h 9b7c09f1e64274d7bb74a57bbfc63778f67b1048 F src/btree_rb.c f30f5cddc4375c05bf361116da1492d9601760ca -F src/build.c 13b6ae48ce71a0f59368f548dba2a662375aeaf6 +F src/build.c 335a4db960a3305e16c64d67726dd534386df7c3 F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73 F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544 -F src/expr.c 3c07e7b5374649c4921b4ff1287f57d513876c3f +F src/expr.c 03c321ac66c1e998c2e0faf22184b5a808b559ca F src/func.c 6b23578d48a8be98a664db145a635c2fa9ddb57b F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 @@ -47,7 +47,7 @@ F src/select.c 2fa83d6c972d3e3f379faee32e3621411490dedb F src/shell.c c2ba26c850874964f5ec1ebf6c43406f28e44c4a F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in dafa83571810b6932f089b589c783355ef7a54b5 -F src/sqliteInt.h e3c756e5aa7bcbf7fbcd20e6aef640c9359c23f2 +F src/sqliteInt.h a57cafea9ef34e73e4504ada4bc70417def67f1e F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95 F src/tclsqlite.c d6860dcd56348b9521726280b72c412d2a33ae97 F src/test1.c b12b585bfb4763df3262975ed8d3f4f274b5eaed @@ -57,7 +57,7 @@ F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/tokenize.c 2ba93fe10d5f57f0cc20b07417c3244a30c324b3 F src/trigger.c 6ff205aaac4869e402d9902e528e1d22a85de14c F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397 -F src/util.c 566c7780170dd11fb1ad5de3ba81f0dfea7cccf0 +F src/util.c 9ab0f573d31ad8c3cf1fcb6bef7a6299e09463fa F src/vacuum.c 0820984615786c9ccdaad8032a792309b354a8eb F src/vdbe.c 779fa3b15148161282a71241ff9733a54a8b0648 F src/vdbe.h d853ed6cc4727fa9e8ace6187c55afcf817041dd @@ -97,7 +97,7 @@ F test/memdb.test cd4580f466f34c42354612a375c5adb90447e4c4 F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90 F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af F test/misc1.test c7dc2f2bd702d8283e885a64ec0714be26cfb051 -F test/misc2.test d8a0b59399a53fd27e74a8fac2a22d5271b9bded +F test/misc2.test 6400032fe041360f717f501930585498853d79ae F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd @@ -168,7 +168,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 -P 8c163fc0c7c721b7a5fa6727b0e90bff4484c782 -R 8fa888001788f8c7b2a2f5a0b6144c1c +P 09c10fe3c99cffc64ed02c2929f206d99c8e3309 +R d2bc63b0694faef8c02f9403066fd889 U drh -Z 5beb2c4636d8c2b6025132999d440be1 +Z 6699c88f8cb611bb62eca292eb62c177 diff --git a/manifest.uuid b/manifest.uuid index da11a89885..744565273d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09c10fe3c99cffc64ed02c2929f206d99c8e3309 \ No newline at end of file +da6273255471673841fdcadc688aeac80722e130 \ No newline at end of file diff --git a/src/build.c b/src/build.c index f92369f23b..0714357618 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.156 2003/07/01 18:13:15 drh Exp $ +** $Id: build.c,v 1.157 2003/07/30 12:34:12 drh Exp $ */ #include "sqliteInt.h" #include @@ -1911,10 +1911,12 @@ IdList *sqliteIdListAppend(IdList *pList, Token *pToken){ if( pList==0 ){ pList = sqliteMalloc( sizeof(IdList) ); if( pList==0 ) return 0; + pList->nAlloc = 0; } - if( (pList->nId & 7)==0 ){ + if( pList->nId>=pList->nAlloc ){ struct IdList_item *a; - a = sqliteRealloc(pList->a, (pList->nId+8)*sizeof(pList->a[0]) ); + pList->nAlloc = pList->nAlloc*2 + 5; + a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) ); if( a==0 ){ sqliteIdListDelete(pList); return 0; @@ -1965,11 +1967,13 @@ SrcList *sqliteSrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ if( pList==0 ){ pList = sqliteMalloc( sizeof(SrcList) ); if( pList==0 ) return 0; + pList->nAlloc = 1; } - if( (pList->nSrc & 7)==1 ){ + if( pList->nSrc>=pList->nAlloc ){ SrcList *pNew; + pList->nAlloc *= 2; pNew = sqliteRealloc(pList, - sizeof(*pList) + (pList->nSrc+8)*sizeof(pList->a[0]) ); + sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) ); if( pNew==0 ){ sqliteSrcListDelete(pList); return 0; diff --git a/src/expr.c b/src/expr.c index 7f3f96f603..804e751b79 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.97 2003/07/20 01:16:47 drh Exp $ +** $Id: expr.c,v 1.98 2003/07/30 12:34:12 drh Exp $ */ #include "sqliteInt.h" #include @@ -160,7 +160,7 @@ ExprList *sqliteExprListDup(ExprList *p){ if( p==0 ) return 0; pNew = sqliteMalloc( sizeof(*pNew) ); if( pNew==0 ) return 0; - pNew->nExpr = p->nExpr; + pNew->nExpr = pNew->nAlloc = p->nExpr; pNew->a = sqliteMalloc( p->nExpr*sizeof(p->a[0]) ); if( pNew->a==0 ) return 0; for(i=0; inExpr; i++){ @@ -189,7 +189,7 @@ SrcList *sqliteSrcListDup(SrcList *p){ nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); pNew = sqliteMalloc( nByte ); if( pNew==0 ) return 0; - pNew->nSrc = p->nSrc; + pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ pNew->a[i].zDatabase = sqliteStrDup(p->a[i].zDatabase); pNew->a[i].zName = sqliteStrDup(p->a[i].zName); @@ -209,7 +209,7 @@ IdList *sqliteIdListDup(IdList *p){ if( p==0 ) return 0; pNew = sqliteMalloc( sizeof(*pNew) ); if( pNew==0 ) return 0; - pNew->nId = p->nId; + pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqliteMalloc( p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ) return 0; for(i=0; inId; i++){ @@ -253,11 +253,12 @@ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ sqliteExprDelete(pExpr); return 0; } + pList->nAlloc = 0; } - if( (pList->nExpr & 7)==0 ){ - int n = pList->nExpr + 8; + if( pList->nAlloc<=pList->nExpr ){ struct ExprList_item *a; - a = sqliteRealloc(pList->a, n*sizeof(pList->a[0])); + pList->nAlloc = pList->nAlloc*2 + 4; + a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0])); if( a==0 ){ sqliteExprDelete(pExpr); return pList; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 465f6af48c..63604d9ea1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.194 2003/07/20 01:16:47 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.195 2003/07/30 12:34:12 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -653,6 +653,7 @@ struct Expr { */ struct ExprList { int nExpr; /* Number of expressions on the list */ + int nAlloc; /* Number of entries allocated below */ struct ExprList_item { Expr *pExpr; /* The list of expressions */ char *zName; /* Token associated with this expression */ @@ -679,6 +680,7 @@ struct ExprList { */ struct IdList { int nId; /* Number of identifiers on the list */ + int nAlloc; /* Number of entries allocated for a[] below */ struct IdList_item { char *zName; /* Name of the identifier */ int idx; /* Index in some Table.aCol[] of a column named zName */ @@ -697,7 +699,8 @@ struct IdList { ** now be identified by a database name, a dot, then the table name: ID.ID. */ struct SrcList { - int nSrc; /* Number of tables or subqueries in the FROM clause */ + u16 nSrc; /* Number of tables or subqueries in the FROM clause */ + u16 nAlloc; /* Number of entries allocated in a[] below */ struct SrcList_item { char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ diff --git a/src/util.c b/src/util.c index be5baa59c2..fcced7e611 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.65 2003/06/05 14:27:56 drh Exp $ +** $Id: util.c,v 1.66 2003/07/30 12:34:12 drh Exp $ */ #include "sqliteInt.h" #include @@ -43,6 +43,10 @@ int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */ static int memcnt = 0; #endif +/* +** Number of 32-bit guard words +*/ +#define N_GUARD 1 /* ** Allocate new memory and set it to zero. Return NULL if @@ -51,7 +55,7 @@ static int memcnt = 0; void *sqliteMalloc_(int n, int bZero, char *zFile, int line){ void *p; int *pi; - int k; + int i, k; if( sqlite_iMallocFail>=0 ){ sqlite_iMallocFail--; if( sqlite_iMallocFail==0 ){ @@ -66,16 +70,16 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){ } if( n==0 ) return 0; k = (n+sizeof(int)-1)/sizeof(int); - pi = malloc( (3+k)*sizeof(int)); + pi = malloc( (N_GUARD*2+1+k)*sizeof(int)); if( pi==0 ){ sqlite_malloc_failed++; return 0; } sqlite_nMalloc++; - pi[0] = 0xdead1122; - pi[1] = n; - pi[k+2] = 0xdead3344; - p = &pi[2]; + for(i=0; i1 fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n", @@ -93,13 +97,17 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){ */ void sqliteCheckMemory(void *p, int N){ int *pi = p; - int n, k; - pi -= 2; - assert( pi[0]==0xdead1122 ); - n = pi[1]; + int n, i, k; + pi -= N_GUARD+1; + for(i=0; i=0 && N1 fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n", ++memcnt, n, (int)p, zFile,line); @@ -136,7 +148,7 @@ void sqliteFree_(void *p, char *zFile, int line){ ** works just like sqliteFree(). */ void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){ - int *oldPi, *pi, k, oldN, oldK; + int *oldPi, *pi, i, k, oldN, oldK; void *p; if( oldP==0 ){ return sqliteMalloc_(n,1,zFile,line); @@ -146,32 +158,34 @@ void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){ return 0; } oldPi = oldP; - oldPi -= 2; + oldPi -= N_GUARD+1; if( oldPi[0]!=0xdead1122 ){ fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)p); return 0; } - oldN = oldPi[1]; + oldN = oldPi[N_GUARD]; oldK = (oldN+sizeof(int)-1)/sizeof(int); - if( oldPi[oldK+2]!=0xdead3344 ){ - fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p); - return 0; + for(i=0; ioldN ? oldN : n); if( n>oldN ){ memset(&((char*)p)[oldN], 0, n-oldN); } - memset(oldPi, 0xab, (oldK+3)*sizeof(int)); + memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int)); free(oldPi); #if MEMORY_DEBUG>1 fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n", diff --git a/test/misc2.test b/test/misc2.test index cb2b53d86f..6b8994fe19 100644 --- a/test/misc2.test +++ b/test/misc2.test @@ -13,7 +13,7 @@ # This file implements tests for miscellanous features that were # left out of other test files. # -# $Id: misc2.test,v 1.5 2003/07/27 17:16:08 drh Exp $ +# $Id: misc2.test,v 1.6 2003/07/30 12:34:13 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -98,3 +98,19 @@ do_test misc2-4.6 { SELECT a FROM t1 WHERE a<1000000000000 ORDER BY 1; } } {1 2147483647 2147483648 4000000000} + +# There were some issues with expanding a SrcList object using a call +# to sqliteSrcListAppend() if the SrcList had previously been duplicated +# using a call to sqliteSrcListDup(). Ticket #416. The following test +# makes sure the problem has been fixed. +# +do_test misc2-5.1 { + execsql { + CREATE TABLE x(a,b); + CREATE VIEW y AS + SELECT x1.b AS p, x2.b AS q FROM x AS x1, x AS x2 WHERE x1.a=x2.a; + CREATE VIEW z AS + SELECT y1.p, y2.p FROM y AS y1, y AS y2 WHERE y1.q=y2.q; + SELECT * from z; + } +} {}