Hello,
proposing small fixes for issues found by ours coverity scanner during static analysis of code.
diff --git a/ext/misc/decimal.c b/ext/misc/decimal.c
index a8d68ac..ed16227 100644
--- a/ext/misc/decimal.c
+++ b/ext/misc/decimal.c
@@ -459,7 +459,10 @@ static void decimalSubFunc(
Decimal *pA = decimal_new(context, argv[0], 0, 0);
Decimal *pB = decimal_new(context, argv[1], 0, 0);
UNUSED_PARAMETER(argc);
- if( pB==0 ) return;
+ if( pB==0 ) {
+ decimal_free(pA);
+ return;
+ }
pB->sign = !pB->sign;
decimal_add(pA, pB);
decimal_result(context, pA);
diff --git a/src/shell.c.in b/src/shell.c.in
index 2d98d23..7db5ff8 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -3843,9 +3843,9 @@ static int run_schema_dump_query(
}else{
rc = SQLITE_CORRUPT;
}
- sqlite3_free(zErr);
free(zQ2);
}
+ sqlite3_free(zErr);
return rc;
}
@@ -6715,6 +6715,7 @@ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
if( rc!=SQLITE_OK ){
raw_printf(stderr, "SQL error: %s\n", zErr);
}
+ sqlite3_free(zErr);
*pRc = rc;
}
}
@@ -8063,6 +8064,7 @@ static int do_meta_command(char *zLine, ShellState *p){
shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
}
+ sqlite3_free(zErrMsg);
}else
if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
Also adding the full report from the scan. Most of the issues I consider as false positives, or low priority problems. The ones I consider as problems are fixed by the provided patch. could you please confirm my thoughts ?
Thank you.
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/shell.c:4963: alloc_fn: Storage is returned from allocation function "decimal_new".
sqlite-src-3350500/shell.c:4963: var_assign: Assigning: "pA" = storage returned from "decimal_new(context, argv[0], 0, NULL)".
sqlite-src-3350500/shell.c:4966: leaked_storage: Variable "pA" going out of scope leaks the storage it points to.
# 4964| Decimal *pB = decimal_new(context, argv[1], 0, 0);
# 4965| UNUSED_PARAMETER(argc);
# 4966|-> if( pB==0 ) return;
# 4967| pB->sign = !pB->sign;
# 4968| decimal_add(pA, pB);
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/shell.c:7131: freed_arg: "zipfileResetCursor" frees "pCsr->pFreeEntry".
sqlite-src-3350500/shell.c:7169: use_after_free: Using freed pointer "pCsr->pFreeEntry".
# 7167| }else{
# 7168| pCsr->bNoop = 1;
# 7169|-> pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
# 7170| rc = zipfileNext(cur);
# 7171| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/shell.c:10206: alias: Assigning: "pScanOrig" = "p->pScan". Now both point to the same storage.
sqlite-src-3350500/shell.c:10237: freed_arg: "idxScanFree" frees "p->pScan".
sqlite-src-3350500/shell.c:10239: use_after_free: Using freed pointer "pScanOrig".
#10237| idxScanFree(p->pScan, pScanOrig);
#10238| idxStatementFree(p->pStatement, pStmtOrig);
#10239|-> p->pScan = pScanOrig;
#10240| p->pStatement = pStmtOrig;
#10241| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/shell.c:10207: alias: Assigning: "pStmtOrig" = "p->pStatement". Now both point to the same storage.
sqlite-src-3350500/shell.c:10238: freed_arg: "idxStatementFree" frees "p->pStatement".
sqlite-src-3350500/shell.c:10240: use_after_free: Using freed pointer "pStmtOrig".
#10238| idxStatementFree(p->pStatement, pStmtOrig);
#10239| p->pScan = pScanOrig;
#10240|-> p->pStatement = pStmtOrig;
#10241| }
#10242|
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/shell.c:13981: alloc_arg: "sqlite3_exec" allocates memory that is stored into "zErr". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/shell.c:14003: leaked_storage: Variable "zErr" going out of scope leaks the storage it points to.
#14001| free(zQ2);
#14002| }
#14003|-> return rc;
#14004| }
#14005|
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/shell.c:16872: alloc_arg: "sqlite3_exec" allocates memory that is stored into "zErr". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/shell.c:16874: noescape: Resource "zErr" is not freed or pointed-to in "fprintf". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/shell.c:16877: leaked_storage: Variable "zErr" going out of scope leaks the storage it points to.
#16875| }
#16876| *pRc = rc;
#16877|-> }
#16878| }
#16879|
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/shell.c:18195: alloc_arg: "sqlite3_exec" allocates memory that is stored into "zErrMsg". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/shell.c:18226: leaked_storage: Variable "zErrMsg" going out of scope leaks the storage it points to.
#18224| raw_printf(p->out, "ANALYZE sqlite_schema;\n");
#18225| }
#18226|-> }else
#18227|
#18228| if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:61126: freed_arg: "walIndexAppend" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:61140: use_after_free: Using freed pointer "pWal->apWiData".
#61138| }
#61139| }
#61140|-> pWal->apWiData[iPg] = aShare;
#61141| nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0);
#61142| nHdr32 = nHdr / sizeof(u32);
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:62019: freed_arg: "sqlite3WalCheckpoint" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:62052: double_free: Calling "sqlite3_free" frees pointer "pWal->apWiData" which has already been freed. [Note: The source code implementation of the function has been overridden by a builtin model.]
#62050| }
#62051| WALTRACE(("WAL%p: closed\n", pWal));
#62052|-> sqlite3_free((void *)pWal->apWiData);
#62053| sqlite3_free(pWal);
#62054| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:63466: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:63466: double_free: Calling "sqlite3WalFindFrame" frees pointer "pWal->apWiData" which has already been freed.
#63464| if( iFirst && (p->pDirty || isCommit==0) ){
#63465| u32 iWrite = 0;
#63466|-> VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
#63467| assert( rc==SQLITE_OK || iWrite==0 );
#63468| if( iWrite>=iFirst ){
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:63466: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:63555: double_free: Calling "walIndexAppend" frees pointer "pWal->apWiData" which has already been freed.
#63553| if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
#63554| iFrame++;
#63555|-> rc = walIndexAppend(pWal, iFrame, p->pgno);
#63556| }
#63557| assert( pLast!=0 || nExtra==0 );
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:63466: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:63561: double_free: Calling "walIndexAppend" frees pointer "pWal->apWiData" which has already been freed.
#63559| iFrame++;
#63560| nExtra--;
#63561|-> rc = walIndexAppend(pWal, iFrame, pLast->pgno);
#63562| }
#63563|
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:63466: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3.c:63576: deref_arg: Calling "walIndexWriteHdr" dereferences freed pointer "pWal->apWiData".
#63574| /* If this is a commit, update the wal-index header too. */
#63575| if( isCommit ){
#63576|-> walIndexWriteHdr(pWal);
#63577| pWal->iCallback = iFrame;
#63578| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:76716: freed_arg: "sqlite3Realloc" frees "pMem->z".
sqlite-src-3350500/sqlite3.c:76717: double_free: Calling "sqlite3_free" frees pointer "pMem->z" which has already been freed. [Note: The source code implementation of the function has been overridden by a builtin model.]
#76715| }else{
#76716| pMem->zMalloc = sqlite3Realloc(pMem->z, n);
#76717|-> if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
#76718| pMem->z = pMem->zMalloc;
#76719| }
Error: BAD_FREE (CWE-590):
sqlite-src-3350500/sqlite3.c:138471: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
sqlite-src-3350500/sqlite3.c:138484: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
sqlite-src-3350500/sqlite3.c:138491: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
#138469| res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
#138470| if( (rc&0xff)==SQLITE_ABORT ){
#138471|-> sqlite3_free_table(&res.azResult[1]);
#138472| if( res.zErrMsg ){
#138473| if( pzErrMsg ){
Error: COPY_PASTE_ERROR (CWE-398):
sqlite-src-3350500/sqlite3.c:156200: original: "pMWin->regStartRowid" looks like the original copy.
sqlite-src-3350500/sqlite3.c:156212: copy_paste_error: "regStartRowid" in "pMWin->regStartRowid" looks like a copy-paste error.
sqlite-src-3350500/sqlite3.c:156212: remediation: Should it say "regEndRowid" instead?
#156210| csr = p->end.csr;
#156211| reg = p->end.reg;
#156212|-> if( pMWin->regStartRowid ){
#156213| assert( pMWin->regEndRowid );
#156214| sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/sqlite3.c:172917: alloc_arg: "fts3DoclistOrMerge" allocates memory that is stored into "aNew".
sqlite-src-3350500/sqlite3.c:172929: var_assign: Assigning: "aMerge" = "aNew".
sqlite-src-3350500/sqlite3.c:172935: leaked_storage: Variable "aNew" going out of scope leaks the storage it points to.
sqlite-src-3350500/sqlite3.c:172937: leaked_storage: Variable "aMerge" going out of scope leaks the storage it points to.
#172935| }
#172936| }
#172937|-> }
#172938| return SQLITE_OK;
#172939| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:176512: freed_arg: "sqlite3_free" frees "pCsr->filter.zTerm". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/sqlite3.c:176547: pass_freed_arg: Passing freed pointer "pCsr->filter.zTerm" as an argument to "sqlite3Fts3SegReaderCursor".
#176545| pCsr->iLangid = iLangVal;
#176546|
#176547|-> rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL,
#176548| pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr
#176549| );
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/sqlite3.c:176983: alloc_fn: Storage is returned from allocation function "fts3ReallocOrFree".
sqlite-src-3350500/sqlite3.c:176983: var_assign: Assigning: "zTemp" = storage returned from "fts3ReallocOrFree(zTemp, nTemp + nByte)".
sqlite-src-3350500/sqlite3.c:176990: noescape: Resource "&zTemp[nTemp]" is not freed or pointed-to in "memcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/sqlite3.c:177032: leaked_storage: Variable "zTemp" going out of scope leaks the storage it points to.
#177030|
#177031| *ppExpr = p;
#177032|-> return rc;
#177033| no_mem:
#177034|
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3.c:227752: freed_arg: "fts5FreeCursorComponents" frees "pCsr->pExpr".
sqlite-src-3350500/sqlite3.c:227877: deref_arg: Calling "fts5CursorFirst" dereferences freed pointer "pCsr->pExpr".
#227875| }else{
#227876| pCsr->ePlan = FTS5_PLAN_MATCH;
#227877|-> rc = fts5CursorFirst(pTab, pCsr, bDesc);
#227878| }
#227879| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:61150: freed_arg: "walIndexAppend" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:61164: use_after_free: Using freed pointer "pWal->apWiData".
#61162| }
#61163| }
#61164|-> pWal->apWiData[iPg] = aShare;
#61165| nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0);
#61166| nHdr32 = nHdr / sizeof(u32);
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:62043: freed_arg: "sqlite3WalCheckpoint" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:62076: double_free: Calling "sqlite3_free" frees pointer "pWal->apWiData" which has already been freed. [Note: The source code implementation of the function has been overridden by a builtin model.]
#62074| }
#62075| WALTRACE(("WAL%p: closed\n", pWal));
#62076|-> sqlite3_free((void *)pWal->apWiData);
#62077| sqlite3_free(pWal);
#62078| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:63490: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:63490: double_free: Calling "sqlite3WalFindFrame" frees pointer "pWal->apWiData" which has already been freed.
#63488| if( iFirst && (p->pDirty || isCommit==0) ){
#63489| u32 iWrite = 0;
#63490|-> VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
#63491| assert( rc==SQLITE_OK || iWrite==0 );
#63492| if( iWrite>=iFirst ){
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:63490: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:63579: double_free: Calling "walIndexAppend" frees pointer "pWal->apWiData" which has already been freed.
#63577| if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
#63578| iFrame++;
#63579|-> rc = walIndexAppend(pWal, iFrame, p->pgno);
#63580| }
#63581| assert( pLast!=0 || nExtra==0 );
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:63490: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:63585: double_free: Calling "walIndexAppend" frees pointer "pWal->apWiData" which has already been freed.
#63583| iFrame++;
#63584| nExtra--;
#63585|-> rc = walIndexAppend(pWal, iFrame, pLast->pgno);
#63586| }
#63587|
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:63490: freed_arg: "sqlite3WalFindFrame" frees "pWal->apWiData".
sqlite-src-3350500/sqlite3_analyzer.c:63600: deref_arg: Calling "walIndexWriteHdr" dereferences freed pointer "pWal->apWiData".
#63598| /* If this is a commit, update the wal-index header too. */
#63599| if( isCommit ){
#63600|-> walIndexWriteHdr(pWal);
#63601| pWal->iCallback = iFrame;
#63602| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:76740: freed_arg: "sqlite3Realloc" frees "pMem->z".
sqlite-src-3350500/sqlite3_analyzer.c:76741: double_free: Calling "sqlite3_free" frees pointer "pMem->z" which has already been freed. [Note: The source code implementation of the function has been overridden by a builtin model.]
#76739| }else{
#76740| pMem->zMalloc = sqlite3Realloc(pMem->z, n);
#76741|-> if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
#76742| pMem->z = pMem->zMalloc;
#76743| }
Error: BAD_FREE (CWE-590):
sqlite-src-3350500/sqlite3_analyzer.c:138495: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
sqlite-src-3350500/sqlite3_analyzer.c:138508: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
sqlite-src-3350500/sqlite3_analyzer.c:138515: address_free: "sqlite3_free_table" frees address of "res.azResult[1]".
#138493| res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
#138494| if( (rc&0xff)==SQLITE_ABORT ){
#138495|-> sqlite3_free_table(&res.azResult[1]);
#138496| if( res.zErrMsg ){
#138497| if( pzErrMsg ){
Error: COPY_PASTE_ERROR (CWE-398):
sqlite-src-3350500/sqlite3_analyzer.c:156224: original: "pMWin->regStartRowid" looks like the original copy.
sqlite-src-3350500/sqlite3_analyzer.c:156236: copy_paste_error: "regStartRowid" in "pMWin->regStartRowid" looks like a copy-paste error.
sqlite-src-3350500/sqlite3_analyzer.c:156236: remediation: Should it say "regEndRowid" instead?
#156234| csr = p->end.csr;
#156235| reg = p->end.reg;
#156236|-> if( pMWin->regStartRowid ){
#156237| assert( pMWin->regEndRowid );
#156238| sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/sqlite3_analyzer.c:172941: alloc_arg: "fts3DoclistOrMerge" allocates memory that is stored into "aNew".
sqlite-src-3350500/sqlite3_analyzer.c:172953: var_assign: Assigning: "aMerge" = "aNew".
sqlite-src-3350500/sqlite3_analyzer.c:172959: leaked_storage: Variable "aNew" going out of scope leaks the storage it points to.
sqlite-src-3350500/sqlite3_analyzer.c:172961: leaked_storage: Variable "aMerge" going out of scope leaks the storage it points to.
#172959| }
#172960| }
#172961|-> }
#172962| return SQLITE_OK;
#172963| }
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:176536: freed_arg: "sqlite3_free" frees "pCsr->filter.zTerm". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/sqlite3_analyzer.c:176571: pass_freed_arg: Passing freed pointer "pCsr->filter.zTerm" as an argument to "sqlite3Fts3SegReaderCursor".
#176569| pCsr->iLangid = iLangVal;
#176570|
#176571|-> rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL,
#176572| pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr
#176573| );
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/sqlite3_analyzer.c:177007: alloc_fn: Storage is returned from allocation function "fts3ReallocOrFree".
sqlite-src-3350500/sqlite3_analyzer.c:177007: var_assign: Assigning: "zTemp" = storage returned from "fts3ReallocOrFree(zTemp, nTemp + nByte)".
sqlite-src-3350500/sqlite3_analyzer.c:177014: noescape: Resource "&zTemp[nTemp]" is not freed or pointed-to in "memcpy". [Note: The source code implementation of the function has been overridden by a builtin model.]
sqlite-src-3350500/sqlite3_analyzer.c:177056: leaked_storage: Variable "zTemp" going out of scope leaks the storage it points to.
#177054|
#177055| *ppExpr = p;
#177056|-> return rc;
#177057| no_mem:
#177058|
Error: USE_AFTER_FREE (CWE-416):
sqlite-src-3350500/sqlite3_analyzer.c:227776: freed_arg: "fts5FreeCursorComponents" frees "pCsr->pExpr".
sqlite-src-3350500/sqlite3_analyzer.c:227901: deref_arg: Calling "fts5CursorFirst" dereferences freed pointer "pCsr->pExpr".
#227899| }else{
#227900| pCsr->ePlan = FTS5_PLAN_MATCH;
#227901|-> rc = fts5CursorFirst(pTab, pCsr, bDesc);
#227902| }
#227903| }
Error: RESOURCE_LEAK (CWE-772):
sqlite-src-3350500/tool/lemon.c:3539: alloc_fn: Storage is returned from allocation function "malloc".
sqlite-src-3350500/tool/lemon.c:3539: var_assign: Assigning: "pathbuf" = storage returned from "malloc((int)strlen(pathlist) + 1)".
sqlite-src-3350500/tool/lemon.c:3558: leaked_storage: Variable "pathbuf" going out of scope leaks the storage it points to.
# 3556| free(pathbufptr);
# 3557| }
# 3558|-> return path;
# 3559| }
# 3560|