This commit is contained in:
parent
e766fba813
commit
918eca635d
|
@ -6268,6 +6268,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s
|
||||||
<alloc init="true">openat</alloc>
|
<alloc init="true">openat</alloc>
|
||||||
<alloc init="true">socket</alloc>
|
<alloc init="true">socket</alloc>
|
||||||
<dealloc>close</dealloc>
|
<dealloc>close</dealloc>
|
||||||
|
<dealloc>fdopen</dealloc>
|
||||||
</resource>
|
</resource>
|
||||||
<resource>
|
<resource>
|
||||||
<alloc init="true">opendir</alloc>
|
<alloc init="true">opendir</alloc>
|
||||||
|
|
|
@ -967,7 +967,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
|
||||||
while (Token::Match(arg, "%name% .|:: %name%"))
|
while (Token::Match(arg, "%name% .|:: %name%"))
|
||||||
arg = arg->tokAt(2);
|
arg = arg->tokAt(2);
|
||||||
|
|
||||||
if (Token::Match(arg, "%var% [-,)] !!.") || Token::Match(arg, "& %var%")) {
|
if (Token::Match(arg, "%var% [-,)] !!.") || Token::Match(arg, "& %var% !!.")) {
|
||||||
// goto variable
|
// goto variable
|
||||||
if (arg->str() == "&")
|
if (arg->str() == "&")
|
||||||
arg = arg->next();
|
arg = arg->next();
|
||||||
|
@ -979,6 +979,9 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
|
||||||
const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName);
|
const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName);
|
||||||
VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName);
|
VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName);
|
||||||
if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) {
|
if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) {
|
||||||
|
if (mSettings->library.getDeallocFuncInfo(tokName)) {
|
||||||
|
changeAllocStatus(varInfo, dealloc.type == 0 ? allocation : dealloc, tokName, arg);
|
||||||
|
}
|
||||||
if (allocFunc->arg == argNr && !(arg->variable() && arg->variable()->isArgument() && arg->valueType() && arg->valueType()->pointer > 1)) {
|
if (allocFunc->arg == argNr && !(arg->variable() && arg->variable()->isArgument() && arg->valueType() && arg->valueType()->pointer > 1)) {
|
||||||
leakIfAllocated(arg, varInfo);
|
leakIfAllocated(arg, varInfo);
|
||||||
VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()];
|
VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()];
|
||||||
|
@ -1063,6 +1066,21 @@ void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Token* getOutparamAllocation(const Token* tok, const Settings* settings)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return nullptr;
|
||||||
|
int argn{};
|
||||||
|
const Token* ftok = getTokenArgumentFunction(tok, argn);
|
||||||
|
if (!ftok)
|
||||||
|
return nullptr;
|
||||||
|
if (const Library::AllocFunc* allocFunc = settings->library.getAllocFuncInfo(ftok)) {
|
||||||
|
if (allocFunc->arg == argn + 1)
|
||||||
|
return ftok;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope)
|
void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope)
|
||||||
{
|
{
|
||||||
const std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
|
const std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
|
||||||
|
@ -1117,7 +1135,9 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't warn when returning after checking return value of outparam allocation
|
// don't warn when returning after checking return value of outparam allocation
|
||||||
if (it->second.allocTok && (tok->scope()->type == Scope::ScopeType::eIf || tok->scope()->type== Scope::ScopeType::eElse)) {
|
const Token* outparamFunc{};
|
||||||
|
if ((tok->scope()->type == Scope::ScopeType::eIf || tok->scope()->type== Scope::ScopeType::eElse) &&
|
||||||
|
(outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) {
|
||||||
const Scope* scope = tok->scope();
|
const Scope* scope = tok->scope();
|
||||||
if (scope->type == Scope::ScopeType::eElse) {
|
if (scope->type == Scope::ScopeType::eElse) {
|
||||||
scope = scope->bodyStart->tokAt(-2)->scope();
|
scope = scope->bodyStart->tokAt(-2)->scope();
|
||||||
|
@ -1125,11 +1145,22 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
|
||||||
const Token* const ifEnd = scope->bodyStart->previous();
|
const Token* const ifEnd = scope->bodyStart->previous();
|
||||||
const Token* const ifStart = ifEnd->link();
|
const Token* const ifStart = ifEnd->link();
|
||||||
const Token* const alloc = it->second.allocTok;
|
const Token* const alloc = it->second.allocTok;
|
||||||
if (precedes(ifStart, alloc) && succeeds(ifEnd, alloc)) {
|
if (precedes(ifStart, alloc) && succeeds(ifEnd, alloc)) { // allocation and check in if
|
||||||
int argn{};
|
if (Token::Match(outparamFunc->next()->astParent(), "%comp%"))
|
||||||
if (const Token* ftok = getTokenArgumentFunction(alloc, argn))
|
continue;
|
||||||
if (Token::Match(ftok->next()->astParent(), "%comp%"))
|
} else { // allocation result assigned to variable
|
||||||
|
const Token* const retAssign = outparamFunc->next()->astParent();
|
||||||
|
if (Token::simpleMatch(retAssign, "=") && retAssign->astOperand1()->varId()) {
|
||||||
|
bool isRetComp = false;
|
||||||
|
for (const Token* tok2 = ifStart; tok2 != ifEnd; tok2 = tok2->next()) {
|
||||||
|
if (tok2->varId() == retAssign->astOperand1()->varId()) {
|
||||||
|
isRetComp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isRetComp)
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,6 +398,17 @@ void memleak_asprintf7(const char* fmt, const int arg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void memleak_asprintf8(const char *fmt, const int arg) // #12204
|
||||||
|
{
|
||||||
|
char* ptr;
|
||||||
|
int ret = asprintf(&ptr, fmt, arg);
|
||||||
|
if (-1 == ret) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("%s", ptr);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void memleak_xmalloc()
|
void memleak_xmalloc()
|
||||||
{
|
{
|
||||||
char *p = (char*)xmalloc(10);
|
char *p = (char*)xmalloc(10);
|
||||||
|
|
|
@ -891,6 +891,22 @@ void validCode(va_list valist_arg1, va_list valist_arg2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t N;
|
||||||
|
int* data;
|
||||||
|
} S_memalign;
|
||||||
|
|
||||||
|
S_memalign* posix_memalign_memleak(size_t n) { // #12248
|
||||||
|
S_memalign* s = malloc(sizeof(*s));
|
||||||
|
s->N = n;
|
||||||
|
if (0 != posix_memalign((void**)&s->data, 16, n * sizeof(int))) {
|
||||||
|
free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(s->data, 0, n * sizeof(int));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t nullPointer_send(int socket, const void *buf, size_t len, int flags)
|
ssize_t nullPointer_send(int socket, const void *buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
// cppcheck-suppress nullPointer
|
// cppcheck-suppress nullPointer
|
||||||
|
@ -1060,6 +1076,13 @@ void resourceLeak_fdopen(int fd)
|
||||||
// cppcheck-suppress resourceLeak
|
// cppcheck-suppress resourceLeak
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resourceLeak_fdopen2(const char* fn) // #2767
|
||||||
|
{
|
||||||
|
int fi = open(fn, O_RDONLY);
|
||||||
|
FILE* fd = fdopen(fi, "r");
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
void resourceLeak_mkstemp(char *template)
|
void resourceLeak_mkstemp(char *template)
|
||||||
{
|
{
|
||||||
// cppcheck-suppress unreadVariable
|
// cppcheck-suppress unreadVariable
|
||||||
|
@ -1125,12 +1148,6 @@ void noleak(int x, int y, int z)
|
||||||
close(fd1);
|
close(fd1);
|
||||||
int fd2 = open("a", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
int fd2 = open("a", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
close(fd2);
|
close(fd2);
|
||||||
/* TODO: add configuration for open/fdopen
|
|
||||||
// #2830
|
|
||||||
int fd = open("path", O_RDONLY);
|
|
||||||
FILE *f = fdopen(fd, "rt");
|
|
||||||
fclose(f);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue