From: drh Date: Fri, 16 Sep 2005 02:38:09 +0000 (+0000) Subject: Fix a whole host of newly discovered memory leaks the occur after a X-Git-Tag: version-3.6.10~3463 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53f733c7aeb881b0320c8e64b5bb10b99accd60d;p=thirdparty%2Fsqlite.git Fix a whole host of newly discovered memory leaks the occur after a failure of realloc(). (CVS 2696) FossilOrigin-Name: 4686d649756a0aa301ade901ac49c89a976c5402 --- diff --git a/manifest b/manifest index d4497c55a2..d1beaa67d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sleak:\sa\sfailure\sto\sdeallocate\sthe\sP3\sparameter\son\sa\scall\nto\ssqlite3VdbeChangeP3.\s(CVS\s2695) -D 2005-09-16T00:27:01 +C Fix\sa\swhole\shost\sof\snewly\sdiscovered\smemory\sleaks\sthe\soccur\safter\sa\nfailure\sof\srealloc().\s(CVS\s2696) +D 2005-09-16T02:38:10 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -40,7 +40,7 @@ F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79 F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c 16a0e19460b14d219f39ff5c7a9eef808aa1969c F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d -F src/expr.c 208f8258d5f56c8da7be3e21cce4d3c34ff3e45c +F src/expr.c b8dbd5a30e80b83b0c1e137dcfcd687bd5d2b76c F src/func.c f63d417248808ff2632a3b576536abffcc21d858 F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -58,15 +58,15 @@ F src/os_win.c ed03a35b2894f9b99840415f941a9f8594dea756 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 2b48db1cc6073a6d2577100866db6ae039d20940 F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164 -F src/parse.y 3bceaece9f70571f2770fc88ff175febf6827367 +F src/parse.y 5602d5cb894dda2932bf50b7e88782a4440ae3ae F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4 -F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5 +F src/printf.c bd421c1ad5e01013c89af63c60eab02852ccd15e F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/select.c 9ef1dddd436e1ea86a6bf64ae0ed71bf4a0b894f F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3 F src/sqlite.h.in 461b2535550cf77aedfd44385da11ef7d63e57a2 -F src/sqliteInt.h ae781b257c3a7f47ac774aa8e72d4f396b027e0c +F src/sqliteInt.h cc685a74a0458bc41a34131e7c0b217654558b6c F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c ac94682f9e601dd373912c46414a5a842db2089a F src/test1.c b569b60e35f0e3ea20e5ebfaf6e522a01c08d481 @@ -78,16 +78,16 @@ F src/tokenize.c e1faf5637f3f4f90933785a0ecf64595f3ac3530 F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a F src/update.c c2716c2115533ffae3d08bf8853aaba4f970f37e F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c -F src/util.c 5650f6fe5ee30e0678985ad7b94da91e3f85752b +F src/util.c fa99c441e8ff52c75cde944ea73ea39f6d5a2a09 F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c -F src/vdbe.c 7b20b81b2643c0cc616c3fec6435f13c6e5fa6db +F src/vdbe.c 3cbb9bb5ab70c9587e39a219a2c007ad7bfc70b5 F src/vdbe.h c8e105979fc7aaf5b8004e9621904e3bd096dfa2 F src/vdbeInt.h 3dd2a29c7b0a55404c35f93caae81fb42f4cb70a -F src/vdbeapi.c 72213ce0c1ab8b215b2ae0ed342511bf769c1e60 -F src/vdbeaux.c df2bda6fdd8a7c9e99561b3975f36a2607912791 +F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd +F src/vdbeaux.c e3a815a88bbf68f17880f5bc077e1c35d14b9409 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c fea0744936008831daa17cdc75056c3ca1469690 -F src/where.c 715e317eb37b89961ad7c5515a18f1e2eb1c7fd8 +F src/where.c 53a54c1434be9afa45db3558d9ae09450acea273 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3 F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6 @@ -307,7 +307,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 9b60f48de7fbca96c6e26266a8fb9eed8bc378f2 -R 128fe9626d0d2bd0ae740c2610205a2e +P 714254cbc12564d44548707043fdcdffb17e4fde +R 573a33c72d8fc43cba95874908d9610d U drh -Z ed6250cc3e36da4b3eb7293f20c17966 +Z 49780202b1950719dafef774b50bb8e6 diff --git a/manifest.uuid b/manifest.uuid index 94176b4868..34006565a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -714254cbc12564d44548707043fdcdffb17e4fde \ No newline at end of file +4686d649756a0aa301ade901ac49c89a976c5402 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8754c90695..63240686fd 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.227 2005/09/09 01:33:19 drh Exp $ +** $Id: expr.c,v 1.228 2005/09/16 02:38:10 drh Exp $ */ #include "sqliteInt.h" #include @@ -355,7 +355,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - pParse->apVarExpr = sqliteRealloc(pParse->apVarExpr, + sqlite3ReallocOrFree((void**)&pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } if( !sqlite3_malloc_failed ){ @@ -1291,7 +1291,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ int mem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); - assert( testAddr>0 ); + assert( testAddr>0 || sqlite3_malloc_failed ); sqlite3VdbeAddOp(v, OP_Integer, 1, 0); sqlite3VdbeAddOp(v, OP_MemStore, mem, 1); } diff --git a/src/parse.y b/src/parse.y index 0abcf10642..7601e869ad 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.179 2005/09/11 11:56:28 drh Exp $ +** @(#) $Id: parse.y,v 1.180 2005/09/16 02:38:10 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -756,7 +756,11 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ExprList *pList = sqlite3ExprListAppend(0, X, 0); pList = sqlite3ExprListAppend(pList, Y, 0); A = sqlite3Expr(TK_BETWEEN, W, 0, 0); - if( A ) A->pList = pList; + if( A ){ + A->pList = pList; + }else{ + sqlite3ExprListDelete(pList); + } if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&W->span,&Y->span); } @@ -776,21 +780,31 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { } expr(A) ::= LP(B) select(X) RP(E). { A = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( A ) A->pSelect = X; - if( !A ) sqlite3SelectDelete(X); + if( A ){ + A->pSelect = X; + }else{ + sqlite3SelectDelete(X); + } sqlite3ExprSpan(A,&B,&E); } expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = Y; - if( !A ) sqlite3SelectDelete(Y); + if( A ){ + A->pSelect = Y; + }else{ + sqlite3SelectDelete(Y); + } if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z); A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( A ){ + A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + }else{ + sqlite3SrcListDelete(pSrc); + } if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); } @@ -799,15 +813,20 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); + }else{ + sqlite3SelectDelete(Y); } - if( !p ) sqlite3SelectDelete(Y); } %endif // SQLITE_OMIT_SUBQUERY /* CASE expressions */ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { A = sqlite3Expr(TK_CASE, X, Z, 0); - if( A ) A->pList = Y; + if( A ){ + A->pList = Y; + }else{ + sqlite3ExprListDelete(Y); + } sqlite3ExprSpan(A, &C, &E); } %type case_exprlist {ExprList*} diff --git a/src/printf.c b/src/printf.c index bcd9339403..a669eb8d44 100644 --- a/src/printf.c +++ b/src/printf.c @@ -726,7 +726,11 @@ static void mout(void *arg, const char *zNewText, int nNewChar){ memcpy(pM->zText, pM->zBase, pM->nChar); } }else{ - pM->zText = pM->xRealloc(pM->zText, pM->nAlloc); + char *zNew; + zNew = pM->xRealloc(pM->zText, pM->nAlloc); + if( zNew ){ + pM->zText = zNew; + } } } } @@ -764,7 +768,10 @@ static char *base_vprintf( memcpy(sM.zText, sM.zBase, sM.nChar+1); } }else if( sM.nAlloc>sM.nChar+10 ){ - sM.zText = xRealloc(sM.zText, sM.nChar+1); + char *zNew = xRealloc(sM.zText, sM.nChar+1); + if( zNew ){ + sM.zText = zNew; + } } } return sM.zText; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7e1fbeac55..226edf6a1e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.417 2005/09/13 16:12:47 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.418 2005/09/16 02:38:11 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1400,6 +1400,7 @@ void sqlite3RealToSortable(double r, char *); # define sqlite3CheckMemory(a,b) # define sqlite3MallocX sqlite3Malloc #endif +void sqlite3ReallocOrFree(void**,int); void sqlite3FreeX(void*); void *sqlite3MallocX(int); char *sqlite3MPrintf(const char*, ...); diff --git a/src/util.c b/src/util.c index 58fe0fb58a..bfeaff1e0e 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.144 2005/08/27 01:51:44 drh Exp $ +** $Id: util.c,v 1.145 2005/09/16 02:38:11 drh Exp $ */ #include "sqliteInt.h" #include @@ -366,6 +366,20 @@ char *sqlite3StrNDup(const char *z, int n){ } #endif /* !defined(SQLITE_MEMDEBUG) */ +/* +** Reallocate a buffer to a different size. This is similar to +** sqliteRealloc() except that if the allocation fails the buffer +** is freed. +*/ +void sqlite3ReallocOrFree(void **ppBuf, int newSize){ + void *pNew = sqliteRealloc(*ppBuf, newSize); + if( pNew ){ + *ppBuf = pNew; + }else{ + sqliteFree(*ppBuf); + } +} + /* ** Create a string from the 2nd and subsequent arguments (up to the ** first NULL argument), store the string in memory obtained from diff --git a/src/vdbe.c b/src/vdbe.c index 7b573bb0fe..203e56401d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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.486 2005/09/10 16:46:13 drh Exp $ +** $Id: vdbe.c,v 1.487 2005/09/16 02:38:11 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -4017,7 +4017,7 @@ case OP_ContextPush: { /* no-push */ /* FIX ME: This should be allocated as part of the vdbe at compile-time */ if( i>=p->contextStackDepth ){ p->contextStackDepth = i+1; - p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context)*(i+1)); + sqlite3ReallocOrFree((void**)&p->contextStack, sizeof(Context)*(i+1)); if( p->contextStack==0 ) goto no_mem; } pContext = &p->contextStack[i]; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 1da5a4493a..2fd54f38e3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -308,8 +308,9 @@ void sqlite3_set_auxdata( pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; - pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc); + pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc); if( !pVdbeFunc ) return; + pCtx->pVdbeFunc = pVdbeFunc; memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux)); pVdbeFunc->nAux = iArg+1; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 742436d85e..625f8da453 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -62,18 +62,18 @@ void sqlite3VdbeTrace(Vdbe *p, FILE *trace){ ** elements. */ static void resizeOpArray(Vdbe *p, int N){ - if( p->magic==VDBE_MAGIC_RUN ){ - assert( N==p->nOp ); - p->nOpAlloc = N; - p->aOp = sqliteRealloc(p->aOp, N*sizeof(Op)); - }else if( p->nOpAllocnOpAlloc; + int runMode = p->magic==VDBE_MAGIC_RUN; + if( runMode || p->nOpAllocnOpAlloc = N+100; - pNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op)); + int nNew = N + 100*(!runMode); + int oldSize = p->nOpAlloc; + pNew = sqliteRealloc(p->aOp, nNew*sizeof(Op)); if( pNew ){ + p->nOpAlloc = nNew; p->aOp = pNew; - memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op)); + if( nNew>oldSize ){ + memset(&p->aOp[oldSize], 0, (nNew-oldSize)*sizeof(Op)); + } } } } @@ -102,7 +102,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){ p->nOp++; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, i+1); - if( p->aOp==0 ){ + if( sqlite3_malloc_failed ){ return 0; } pOp = &p->aOp[i]; @@ -147,7 +147,8 @@ int sqlite3VdbeMakeLabel(Vdbe *p){ assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nLabelAlloc ){ p->nLabelAlloc = p->nLabelAlloc*2 + 10; - p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0])); + sqlite3ReallocOrFree((void**)&p->aLabel, + p->nLabelAlloc*sizeof(p->aLabel[0])); } if( p->aLabel ){ p->aLabel[i] = -1; @@ -299,7 +300,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, p->nOp + nOp); - if( p->aOp==0 ){ + if( sqlite3_malloc_failed ){ return 0; } addr = p->nOp; diff --git a/src/where.c b/src/where.c index 1cb479c9ba..be35a110cf 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.171 2005/09/10 16:46:13 drh Exp $ +** $Id: where.c,v 1.172 2005/09/16 02:38:11 drh Exp $ */ #include "sqliteInt.h" @@ -656,7 +656,11 @@ static void exprAnalyze( pDup->iColumn = iColumn; } pNew = sqlite3Expr(TK_IN, pDup, 0, 0); - if( pNew ) pNew->pList = pList; + if( pNew ){ + pNew->pList = pList; + }else{ + sqlite3ExprListDelete(pList); + } pTerm->pExpr = pNew; pTerm->flags |= TERM_DYNAMIC; exprAnalyze(pSrc, pMaskSet, pWC, idxTerm); @@ -1152,8 +1156,9 @@ static void codeEqualityTerm( sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); pLevel->nIn++; - pLevel->aInLoop = aIn = sqliteRealloc(pLevel->aInLoop, + sqlite3ReallocOrFree((void**)&pLevel->aInLoop, sizeof(pLevel->aInLoop[0])*3*pLevel->nIn); + aIn = pLevel->aInLoop; if( aIn ){ aIn += pLevel->nIn*3 - 3; aIn[0] = OP_Next;