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

@ -91,7 +91,41 @@
<arg nr="1"><not-uninit/><not-null/></arg>
<arg nr="2"><not-uninit/><not-null/></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>
<dealloc>free</dealloc>
<alloc init="true">strdup</alloc>

View File

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

View File

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

View File

@ -214,13 +214,13 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
ArgumentChecks::MinSize::Type type;
if (strcmp(typeattr,"strlen")==0)
type = ArgumentChecks::MinSize::Type::STRLEN;
type = ArgumentChecks::MinSize::STRLEN;
else if (strcmp(typeattr,"argvalue")==0)
type = ArgumentChecks::MinSize::Type::ARGVALUE;
type = ArgumentChecks::MinSize::ARGVALUE;
else if (strcmp(typeattr,"sizeof")==0)
type = ArgumentChecks::MinSize::Type::SIZEOF;
type = ArgumentChecks::MinSize::SIZEOF;
else if (strcmp(typeattr,"mul")==0)
type = ArgumentChecks::MinSize::Type::MUL;
type = ArgumentChecks::MinSize::MUL;
else
return Error(BAD_ATTRIBUTE_VALUE, typeattr);
@ -231,7 +231,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
return Error(BAD_ATTRIBUTE_VALUE, argattr);
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");
if (!arg2attr)
return Error(MISSING_ATTRIBUTE, "arg2");

View File

@ -96,6 +96,30 @@ private:
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() {
TEST_CASE(noerr1);
@ -169,6 +193,7 @@ private:
TEST_CASE(array_index_valueflow);
TEST_CASE(buffer_overrun_1_standard_functions);
TEST_CASE(buffer_overrun_1_posix_functions);
TEST_CASE(buffer_overrun_2_struct);
TEST_CASE(buffer_overrun_3);
TEST_CASE(buffer_overrun_4);
@ -2097,63 +2122,63 @@ private:
}
void buffer_overrun_1_posix_functions() {
check("void f(int fd)\n"
checkposix("void f(int fd)\n"
"{\n"
" char str[3];\n"
" read(fd, str, 3);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(int fd)\n"
checkposix("void f(int fd)\n"
"{\n"
" char str[3];\n"
" read(fd, str, 4);\n"
"}");
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"
" char str[3];\n"
" write(fd, str, 3);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(int fd)\n"
checkposix("void f(int fd)\n"
"{\n"
" char str[3];\n"
" write(fd, str, 4);\n"
"}");
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"
" long bb[2];\n"
" write(stdin, bb, sizeof(bb));\n"
"}", false, "test.cpp", false);
"}");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
checkposix("void f()\n"
"{\n"
"char str[3];\n"
"recv(s, str, 4, 0);\n"
"}");
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"
"char str[3];\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());
check("void f()\n"
checkposix("void f()\n"
"{\n"
"char str[3];\n"
"send(s, str, 4, 0);\n"
"}");
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"
"char str[3];\n"
"sendto(s, str, 4, 0, 0x0, 0x0);\n"