TestMemLeak: moved posix.cfg tests

This commit is contained in:
Daniel Marjamäki 2015-02-15 18:11:09 +01:00
parent adedb5a888
commit fe8ba51f03
3 changed files with 66 additions and 127 deletions

View File

@ -264,6 +264,12 @@
<not-null/> <not-null/>
</arg> </arg>
</function> </function>
<function name="fdopendir">
<noreturn>false</noreturn>
<arg nr="1">
<not-uninit/>
</arg>
</function>
<function name="isatty"> <function name="isatty">
<noreturn>false</noreturn> <noreturn>false</noreturn>
<arg nr="1"> <arg nr="1">
@ -289,6 +295,19 @@
<not-uninit/> <not-uninit/>
</arg> </arg>
</function> </function>
<!-- int socket(int domain, int type, int protocol); -->
<function name="socket">
<noreturn>false</noreturn>
<arg nr="1">
<not-uninit/>
</arg>
<arg nr="2">
<not-uninit/>
</arg>
<arg nr="3">
<not-uninit/>
</arg>
</function>
<!-- int close(int fildes); --> <!-- int close(int fildes); -->
<function name="close"> <function name="close">
<noreturn>false</noreturn> <noreturn>false</noreturn>

View File

@ -7,9 +7,15 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0 // No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
// //
#include <stdio.h> // <- FILE
#include <dirent.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
void bufferAccessOutOf(int fd) {
void bufferAccessOutOfBounds(int fd) {
char a[5]; char a[5];
read(fd,a,5); read(fd,a,5);
// cppcheck-suppress bufferAccessOutOfBounds // cppcheck-suppress bufferAccessOutOfBounds
@ -32,7 +38,7 @@ void bufferAccessOutOf(int fd) {
0; 0;
} }
void f(char *p) { void nullPointer(char *p) {
isatty (0); isatty (0);
mkdir (p, 0); mkdir (p, 0);
getcwd (0, 0); getcwd (0, 0);
@ -40,3 +46,41 @@ void f(char *p) {
readdir (0); readdir (0);
} }
void memleak_mmap(int fd) {
void *addr = mmap(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);
// cppcheck-suppress memleak
}
/* TODO: add configuration for fdopen
void resourceLeak_fdopen(int fd) {
FILE *f = fdopen(fd, "r");
// cppcheck-suppress resourceLeak
}
*/
void resourceLeak_fdopendir(int fd) {
DIR* leak1 = fdopendir(fd);
// cppcheck-suppress resourceLeak
}
void resourceLeak_opendir(void) {
DIR* leak1 = opendir("abc");
// cppcheck-suppress resourceLeak
}
void resourceLeak_socket(void) {
int s = socket(AF_INET, SOCK_STREAM, 0);
// cppcheck-suppress resourceLeak
}
void noleak(int x, int y, int z) {
DIR *p1 = fdopendir(x); closedir(p1);
DIR *p2 = opendir("abc"); closedir(p2);
int s = socket(AF_INET,SOCK_STREAM,0); close(s);
/* TODO: add configuration for open/fdopen
// #2830
int fd = open("path", O_RDONLY);
FILE *f = fdopen(fd, "rt");
fclose(f);
*/
}

View File

@ -100,7 +100,6 @@ private:
errout.str(""); errout.str("");
Settings settings; Settings settings;
settings.standards.posix = true;
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
@ -330,7 +329,6 @@ private:
TEST_CASE(tmpfile_function); TEST_CASE(tmpfile_function);
TEST_CASE(fcloseall_function); TEST_CASE(fcloseall_function);
TEST_CASE(file_functions); TEST_CASE(file_functions);
TEST_CASE(posix_rewinddir);
TEST_CASE(getc_function); TEST_CASE(getc_function);
TEST_CASE(open_function); TEST_CASE(open_function);
@ -366,10 +364,6 @@ private:
TEST_CASE(c_code); TEST_CASE(c_code);
// test that the cfg files are configured correctly
TEST_CASE(posixcfg);
TEST_CASE(posixcfg_mmap);
TEST_CASE(gnucfg); TEST_CASE(gnucfg);
} }
@ -3700,22 +3694,13 @@ private:
Settings settings; Settings settings;
settings.standards.posix = true; settings.standards.posix = true;
check("void f()\n" check("void f() {\n"
"{\n"
" FILE *f = popen (\"test\", \"w\");\n" " FILE *f = popen (\"test\", \"w\");\n"
" int a = pclose(f);\n" " int a = pclose(f);\n"
"}", &settings); "}", &settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void posix_rewinddir() {
Settings settings;
settings.standards.posix = true;
check("void f(DIR *p) { rewinddir(p); }", &settings);
ASSERT_EQUALS("", errout.str());
}
void exit2() { void exit2() {
check("void f()\n" check("void f()\n"
"{\n" "{\n"
@ -4280,114 +4265,6 @@ private:
check(code, &settings); check(code, &settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: p\n", errout.str());
} }
// Test that posix.cfg is configured correctly
void posixcfg() {
Settings settings;
settings.standards.posix = true;
LOAD_LIB_2(settings.library, "posix.cfg");
const char code[] = "void leaks() {\n"
" void* leak1 = fdopendir();\n"
" void* leak2 = opendir();\n"
" void* leak3 = socket();\n"
"}\n"
"void noleaks() {\n"
" void *p1 = fdopendir(); closedir(p1);\n"
" void *p2 = opendir(); closedir(p2);\n"
" void *p3 = socket(); close(p3);\n"
"}";
check(code, &settings);
ASSERT_EQUALS("[test.cpp:5]: (error) Resource leak: leak1\n"
"[test.cpp:5]: (error) Resource leak: leak2\n"
"[test.cpp:5]: (error) Resource leak: leak3\n", errout.str());
const char code2[] = "int main() {\n"
" int fileDescriptor = socket(AF_INET, SOCK_STREAM, 0);\n"
" close(fileDescriptor);\n"
"}";
check(code2, &settings);
ASSERT_EQUALS("", errout.str());
// Ticket #2830
check("void f(const char *path) {\n"
" int fd = open(path, O_RDONLY);\n"
" FILE *f = fdopen(fd, x);\n"
" fclose(f);\n"
"}", &settings);
ASSERT_EQUALS("", errout.str());
// Ticket #1416
check("void f(void) {\n"
" FILE *f = fdopen(0, \"r\");\n"
"}", &settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Resource leak: f\n", errout.str());
// strdupa allocates on the stack, no free() needed
check("void x()\n"
"{\n"
" char *s = strdupa(\"Test\");\n"
"}", &settings);
ASSERT_EQUALS("", errout.str());
LOAD_LIB_2(settings.library, "gtk.cfg");
check("void f(char *a) {\n"
" char *s = g_strdup(a);\n"
" mkstemp(s);\n"
" mkdtemp(s);\n"
" mktemp(s);\n"
"}", &settings);
ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: s\n", errout.str());
}
void posixcfg_mmap() {
Settings settings;
settings.standards.posix = true;
LOAD_LIB_2(settings.library, "posix.cfg");
// normal mmap
check("void f(int fd) {\n"
" char *addr = mmap(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
" munmap(addr, 255);\n"
"}", &settings);
ASSERT_EQUALS("", errout.str());
// mmap64 - large file support
check("void f(int fd) {\n"
" char *addr = mmap64(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
" munmap(addr, 255);\n"
"}", &settings);
ASSERT_EQUALS("", errout.str());
// pass in fixed address
check("void f(int fd) {\n"
" void *fixed_addr = 123;\n"
" void *mapped_addr = mmap(fixed_addr, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
" munmap(mapped_addr, 255);\n"
"}", &settings);
ASSERT_EQUALS("", errout.str());
// no munmap()
check("void f(int fd) {\n"
" void *addr = mmap(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
"}", &settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: addr\n", errout.str());
// wrong deallocator
check("void f(int fd) {\n"
" void *addr = mmap(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
" free(addr);\n"
"}", &settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Mismatching allocation and deallocation: addr\n", errout.str());
// wrong deallocator for mmap64
check("void f(int fd) {\n"
" void *addr = mmap64(NULL, 255, PROT_NONE, MAP_PRIVATE, fd, 0);\n"
" free(addr);\n"
"}", &settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Mismatching allocation and deallocation: addr\n", errout.str());
}
}; };
static TestMemleakInFunction testMemleakInFunction; static TestMemleakInFunction testMemleakInFunction;
@ -6313,7 +6190,6 @@ private:
} }
void run() { void run() {
settings.standards.posix = true;
settings.inconclusive = true; settings.inconclusive = true;
settings.addEnabled("warning"); settings.addEnabled("warning");