Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix two obscure memory leaks that can follow a malloc() failure in sqlite3_set_auxdata(). Ticket #2534. (CVS 4185) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b88af1827bec3e8a32450dd0a073ffc3 |
User & Date: | danielk1977 2007-07-26 06:50:06.000 |
Context
2007-07-26
| ||
10:16 | Test that an explicit collation sequence overrides an implicit one attached to a 'new' reference (it does). No code changes. (CVS 4186) (check-in: a443b07ed6 user: danielk1977 tags: trunk) | |
06:50 | Fix two obscure memory leaks that can follow a malloc() failure in sqlite3_set_auxdata(). Ticket #2534. (CVS 4185) (check-in: b88af1827b user: danielk1977 tags: trunk) | |
2007-07-25
| ||
00:56 | Implement xRename() for fts1 so that it is possible to rename fts1 tables. See http://www.sqlite.org/cvstrac/chngview?cn=4143 (CVS 4184) (check-in: febf75f022 user: shess tags: trunk) | |
Changes
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.163 2007/07/26 06:50:06 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* #include <math.h> */ #include <stdlib.h> #include <assert.h> #include "vdbeInt.h" |
︙ | ︙ | |||
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 | for(i=0; i<nArg; i++){ char const *z = (char*)sqlite3_value_text(argv[i]); if( z ){ char *zAux = sqlite3_get_auxdata(pCtx, i); if( zAux ){ zRet[i*2] = '1'; if( strcmp(zAux, z) ){ sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; zAux = sqliteStrDup(z); sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); | > | 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 | for(i=0; i<nArg; i++){ char const *z = (char*)sqlite3_value_text(argv[i]); if( z ){ char *zAux = sqlite3_get_auxdata(pCtx, i); if( zAux ){ zRet[i*2] = '1'; if( strcmp(zAux, z) ){ free_test_auxdata((void *)zRet); sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; zAux = sqliteStrDup(z); sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.639 2007/07/26 06:50:06 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <math.h> #include "vdbeInt.h" |
︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 | assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; | | > > > > > > > > > > > > | 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( sqlite3MallocFailed() ){ /* Even though a malloc() has failed, the implementation of the ** user function may have called an sqlite3_result_XXX() function ** to return a value. The following call releases any resources ** associated with such a value. ** ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn() ** fails also (the if(...) statement above). But if people are ** misusing sqlite, they have bigger problems than a leaked value. */ sqlite3VdbeMemRelease(&ctx.s); goto no_mem; } popStack(&pTos, n); /* If any auxilary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ if( ctx.pVdbeFunc ){ sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
386 387 388 389 390 391 392 | sqlite3_context *pCtx, int iArg, void *pAux, void (*xDelete)(void*) ){ struct AuxData *pAuxData; VdbeFunc *pVdbeFunc; | | | > > > > > > | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | sqlite3_context *pCtx, int iArg, void *pAux, void (*xDelete)(void*) ){ struct AuxData *pAuxData; VdbeFunc *pVdbeFunc; if( iArg<0 ) goto failed; pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc); if( !pVdbeFunc ) goto failed; pCtx->pVdbeFunc = pVdbeFunc; memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux)); pVdbeFunc->nAux = iArg+1; pVdbeFunc->pFunc = pCtx->pFunc; } pAuxData = &pVdbeFunc->apAux[iArg]; if( pAuxData->pAux && pAuxData->xDelete ){ pAuxData->xDelete(pAuxData->pAux); } pAuxData->pAux = pAux; pAuxData->xDelete = xDelete; return; failed: if( xDelete ){ xDelete(pAux); } } /* ** Return the number of times the Step function of a aggregate has been ** called. ** ** This function is deprecated. Do not use it for new code. It is |
︙ | ︙ |
Changes to test/mallocB.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file contains additional out-of-memory checks (see malloc.tcl). # These were all discovered by fuzzy generation of SQL. Apart from # that they have little in common. # | > | > > > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file contains additional out-of-memory checks (see malloc.tcl). # These were all discovered by fuzzy generation of SQL. Apart from # that they have little in common. # # # $Id: mallocB.test,v 1.3 2007/07/26 06:50:06 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl # Only run these tests if memory debugging is turned on. # if {[info command sqlite_malloc_stat]==""} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test return } do_malloc_test mallocB-1 -sqlbody {SELECT - 456} do_malloc_test mallocB-2 -sqlbody {SELECT - 456.1} do_malloc_test mallocB-3 -sqlbody {SELECT random()} do_malloc_test mallocB-4 -sqlbody {SELECT zeroblob(1000)} do_malloc_test mallocB-5 -sqlbody {SELECT * FROM (SELECT 1) GROUP BY 1;} # The following test checks that there are no resource leaks following a # malloc() failure in sqlite3_set_auxdata(). # # Note: This problem was not discovered by fuzzy generation of SQL. Not # that it really matters. # do_malloc_test mallocB-6 -sqlbody { SELECT test_auxdata('hello world'); } sqlite_malloc_fail 0 finish_test |