Skip to content

Commit

Permalink
Fix #11043 FN: memleak posix getline / #12297 FP: memleak (#6103)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Mar 8, 2024
1 parent f97bab8 commit 7842ae4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 9 deletions.
9 changes: 6 additions & 3 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -987,10 +987,11 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin

if (Token::Match(arg, "%var% [-,)] !!.") || Token::Match(arg, "& %var% !!.")) {
// goto variable
if (arg->str() == "&")
const bool isAddressOf = arg->str() == "&";
if (isAddressOf)
arg = arg->next();

const bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0;
const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->values().front().intvalue == 0);

// Is variable allocated?
if (!isnull && (!af || af->arg == argNr)) {
Expand All @@ -1000,7 +1001,9 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
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) &&
(isAddressOf || (arg->valueType() && arg->valueType()->pointer == 2))) {
leakIfAllocated(arg, varInfo);
VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()];
varAlloc.type = allocFunc->groupId;
Expand Down
16 changes: 14 additions & 2 deletions test/cfg/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,12 +1035,13 @@ void nullPointer_pthread_create() // #12396
pthread_create(&thread, NULL, (void* (*)(void*))f_returns_NULL, NULL);
}

void memleak_getaddrinfo()
void memleak_getaddrinfo() // #6994
{
//TODO: nothing to report yet, see http://sourceforge.net/p/cppcheck/discussion/general/thread/d9737d5d/
struct addrinfo * res=NULL;
getaddrinfo("node", NULL, NULL, &res);
freeaddrinfo(res);
getaddrinfo("node", NULL, NULL, &res);
// cppcheck-suppress memleak
}

void memleak_mmap(int fd)
Expand All @@ -1058,6 +1059,17 @@ void * memleak_mmap2() // #8327
return NULL;
}

void memleak_getline() { // #11043
char *line = NULL;
size_t size = 0;
getline(&line, &size, stdin);
// cppcheck-suppress memleak
line = NULL;
getline(&line, &size, stdin);
// cppcheck-suppress memleak
line = NULL;
}

void * identicalCondition_mmap(int fd, size_t size) // #9940
{
void* buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Expand Down
2 changes: 1 addition & 1 deletion test/cfg/windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ void memleak_AllocateAndInitializeSid()
PSID pEveryoneSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID);
// TODO: enable when #6994 is implemented cppcheck-suppress memleak
// cppcheck-suppress memleak
}

void memleak_HeapAlloc()
Expand Down
39 changes: 36 additions & 3 deletions test/testleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
#include <string>
#include <vector>

class TestLeakAutoVarStrcpy;
class TestLeakAutoVarWindows;

class TestLeakAutoVar : public TestFixture {
public:
TestLeakAutoVar() : TestFixture("TestLeakAutoVar") {}
Expand Down Expand Up @@ -3291,3 +3288,39 @@ class TestLeakAutoVarWindows : public TestFixture {
};

REGISTER_TEST(TestLeakAutoVarWindows)

class TestLeakAutoVarPosix : public TestFixture {
public:
TestLeakAutoVarPosix() : TestFixture("TestLeakAutoVarPosix") {}

private:
const Settings settings = settingsBuilder().library("std.cfg").library("posix.cfg").build();

void check_(const char* file, int line, const char code[]) {
// Clear the error buffer..
errout.str("");

// Tokenize..
Tokenizer tokenizer(settings, this);
std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);

// Check for leaks..
runChecks<CheckLeakAutoVar>(tokenizer, this);
}

void run() override {
TEST_CASE(memleak_getline);
}

void memleak_getline() {
check("void f(std::ifstream &is) {\n" // #12297
" std::string str;\n"
" if (getline(is, str, 'x').good()) {};\n"
" if (!getline(is, str, 'x').good()) {};\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
};

REGISTER_TEST(TestLeakAutoVarPosix)

0 comments on commit 7842ae4

Please sign in to comment.