Add some more functions to posix.cfg which allow to enable TestBufferOverrun::buffer_overrun_1_posix_functions

Fix some compiler warnings on MSVC
This commit is contained in:
amai2012 2014-07-05 22:47:10 +02:00
parent a3acc3241e
commit 77095e2b05
5 changed files with 87 additions and 22 deletions

View File

@ -92,6 +92,40 @@
<arg nr="2"><not-uninit/><not-null/></arg> <arg nr="2"><not-uninit/><not-null/></arg>
<arg nr="3"><not-bool/><valid>0:</valid></arg> <arg nr="3"><not-bool/><valid>0:</valid></arg>
</function> </function>
<function name="read">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
</function>
<function name="write">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
</function>
<function name="recv">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
<arg nr="4"><not-uninit/></arg>
</function>
<function name="recvfrom">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
<arg nr="4"><not-uninit/></arg>
</function>
<function name="send">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
<arg nr="4"><not-uninit/></arg>
</function>
<function name="sendto">
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><minsize type="argvalue" arg="3"/></arg>
<arg nr="3"><not-uninit/></arg>
<arg nr="4"><not-uninit/></arg>
</function>
<memory> <memory>
<dealloc>free</dealloc> <dealloc>free</dealloc>
<alloc init="true">strdup</alloc> <alloc init="true">strdup</alloc>

View File

@ -460,8 +460,14 @@ unsigned int __stdcall ThreadExecutor::threadProc(void *args)
LeaveCriticalSection(&threadExecutor->_fileSync); LeaveCriticalSection(&threadExecutor->_fileSync);
}; };
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning( disable : 4702 )
#endif
return result; return result;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
} }
void ThreadExecutor::reportOut(const std::string &outmsg) void ThreadExecutor::reportOut(const std::string &outmsg)

View File

@ -287,7 +287,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &ftok, unsigned int
if (!argtok) if (!argtok)
break; break;
switch (minsize->type) { switch (minsize->type) {
case Library::ArgumentChecks::MinSize::Type::ARGVALUE: case Library::ArgumentChecks::MinSize::ARGVALUE:
if (Token::Match(argtok, "%num% ,|)")) { if (Token::Match(argtok, "%num% ,|)")) {
const MathLib::bigint sz = MathLib::toLongNumber(argtok->str()); const MathLib::bigint sz = MathLib::toLongNumber(argtok->str());
if (sz > arraySize) if (sz > arraySize)
@ -295,7 +295,7 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &ftok, unsigned int
} else if (argtok->type() == Token::eChar && Token::Match(argtok->next(), ",|)")) } else if (argtok->type() == Token::eChar && Token::Match(argtok->next(), ",|)"))
sizeArgumentAsCharError(argtok); sizeArgumentAsCharError(argtok);
break; break;
case Library::ArgumentChecks::MinSize::Type::MUL: case Library::ArgumentChecks::MinSize::MUL:
// TODO: handle arbitrary arg2 // TODO: handle arbitrary arg2
if (minsize->arg2 == minsize->arg+1 && Token::Match(argtok, "%num% , %num% ,|)")) { if (minsize->arg2 == minsize->arg+1 && Token::Match(argtok, "%num% , %num% ,|)")) {
const MathLib::bigint sz = MathLib::toLongNumber(argtok->str()) * MathLib::toLongNumber(argtok->strAt(2)); const MathLib::bigint sz = MathLib::toLongNumber(argtok->str()) * MathLib::toLongNumber(argtok->strAt(2));
@ -303,15 +303,15 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &ftok, unsigned int
error = true; error = true;
} }
break; break;
case Library::ArgumentChecks::MinSize::Type::STRLEN: case Library::ArgumentChecks::MinSize::STRLEN:
if (argtok->type() == Token::eString && Token::getStrLength(argtok) >= arraySize) if (argtok->type() == Token::eString && Token::getStrLength(argtok) >= arraySize)
error = true; error = true;
break; break;
case Library::ArgumentChecks::MinSize::Type::SIZEOF: case Library::ArgumentChecks::MinSize::SIZEOF:
if (argtok->type() == Token::eString && Token::getStrLength(argtok) >= arraySize) if (argtok->type() == Token::eString && Token::getStrLength(argtok) >= arraySize)
error = true; error = true;
break; break;
case Library::ArgumentChecks::MinSize::Type::NONE: case Library::ArgumentChecks::MinSize::NONE:
break; break;
}; };
} }

View File

@ -214,13 +214,13 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
ArgumentChecks::MinSize::Type type; ArgumentChecks::MinSize::Type type;
if (strcmp(typeattr,"strlen")==0) if (strcmp(typeattr,"strlen")==0)
type = ArgumentChecks::MinSize::Type::STRLEN; type = ArgumentChecks::MinSize::STRLEN;
else if (strcmp(typeattr,"argvalue")==0) else if (strcmp(typeattr,"argvalue")==0)
type = ArgumentChecks::MinSize::Type::ARGVALUE; type = ArgumentChecks::MinSize::ARGVALUE;
else if (strcmp(typeattr,"sizeof")==0) else if (strcmp(typeattr,"sizeof")==0)
type = ArgumentChecks::MinSize::Type::SIZEOF; type = ArgumentChecks::MinSize::SIZEOF;
else if (strcmp(typeattr,"mul")==0) else if (strcmp(typeattr,"mul")==0)
type = ArgumentChecks::MinSize::Type::MUL; type = ArgumentChecks::MinSize::MUL;
else else
return Error(BAD_ATTRIBUTE_VALUE, typeattr); return Error(BAD_ATTRIBUTE_VALUE, typeattr);
@ -231,7 +231,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
return Error(BAD_ATTRIBUTE_VALUE, argattr); return Error(BAD_ATTRIBUTE_VALUE, argattr);
minsizes.push_back(ArgumentChecks::MinSize(type,argattr[0]-'0')); minsizes.push_back(ArgumentChecks::MinSize(type,argattr[0]-'0'));
if (type == ArgumentChecks::MinSize::Type::MUL) { if (type == ArgumentChecks::MinSize::MUL) {
const char *arg2attr = argnode->Attribute("arg2"); const char *arg2attr = argnode->Attribute("arg2");
if (!arg2attr) if (!arg2attr)
return Error(MISSING_ATTRIBUTE, "arg2"); return Error(MISSING_ATTRIBUTE, "arg2");

View File

@ -96,6 +96,30 @@ private:
checkBufferOverrun.writeOutsideBufferSize(); checkBufferOverrun.writeOutsideBufferSize();
} }
void checkposix(const char code[], const char filename[] = "test.cpp") {
static bool init;
static Settings settings;
if (!init) {
init = true;
LOAD_LIB_2(settings.library, "posix.cfg");
settings.addEnabled("warning");
}
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
// Clear the error buffer..
errout.str("");
// Check for buffer overruns..
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings, this);
checkBufferOverrun.bufferOverrun();
checkBufferOverrun.bufferOverrun2();
checkBufferOverrun.arrayIndexThenCheck();
checkBufferOverrun.writeOutsideBufferSize();
}
void run() { void run() {
TEST_CASE(noerr1); TEST_CASE(noerr1);
@ -169,6 +193,7 @@ private:
TEST_CASE(array_index_valueflow); TEST_CASE(array_index_valueflow);
TEST_CASE(buffer_overrun_1_standard_functions); TEST_CASE(buffer_overrun_1_standard_functions);
TEST_CASE(buffer_overrun_1_posix_functions);
TEST_CASE(buffer_overrun_2_struct); TEST_CASE(buffer_overrun_2_struct);
TEST_CASE(buffer_overrun_3); TEST_CASE(buffer_overrun_3);
TEST_CASE(buffer_overrun_4); TEST_CASE(buffer_overrun_4);
@ -2097,63 +2122,63 @@ private:
} }
void buffer_overrun_1_posix_functions() { void buffer_overrun_1_posix_functions() {
check("void f(int fd)\n" checkposix("void f(int fd)\n"
"{\n" "{\n"
" char str[3];\n" " char str[3];\n"
" read(fd, str, 3);\n" " read(fd, str, 3);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int fd)\n" checkposix("void f(int fd)\n"
"{\n" "{\n"
" char str[3];\n" " char str[3];\n"
" read(fd, str, 4);\n" " read(fd, str, 4);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str());
check("void f(int fd)\n" checkposix("void f(int fd)\n"
"{\n" "{\n"
" char str[3];\n" " char str[3];\n"
" write(fd, str, 3);\n" " write(fd, str, 3);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int fd)\n" checkposix("void f(int fd)\n"
"{\n" "{\n"
" char str[3];\n" " char str[3];\n"
" write(fd, str, 4);\n" " write(fd, str, 4);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str());
check("void f()\n" checkposix("void f()\n"
"{\n" "{\n"
" long bb[2];\n" " long bb[2];\n"
" write(stdin, bb, sizeof(bb));\n" " write(stdin, bb, sizeof(bb));\n"
"}", false, "test.cpp", false); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f()\n" checkposix("void f()\n"
"{\n" "{\n"
"char str[3];\n" "char str[3];\n"
"recv(s, str, 4, 0);\n" "recv(s, str, 4, 0);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str());
check("void f()\n" checkposix("void f()\n"
"{\n" "{\n"
"char str[3];\n" "char str[3];\n"
"recvfrom(s, str, 4, 0, 0x0, 0x0);\n" "recvfrom(s, str, 4, 0, 0x0, 0x0);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str());
check("void f()\n" checkposix("void f()\n"
"{\n" "{\n"
"char str[3];\n" "char str[3];\n"
"send(s, str, 4, 0);\n" "send(s, str, 4, 0);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: str\n", errout.str());
check("void f()\n" checkposix("void f()\n"
"{\n" "{\n"
"char str[3];\n" "char str[3];\n"
"sendto(s, str, 4, 0, 0x0, 0x0);\n" "sendto(s, str, 4, 0, 0x0, 0x0);\n"