diff --git a/cfg/posix.cfg b/cfg/posix.cfg index 1acedb8b8..fc95aeb6d 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -91,7 +91,41 @@ 0: - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + free strdup diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index aed99fe8f..366788823 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -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) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 3b5fb855b..4c9f5e920 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -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; }; } diff --git a/lib/library.cpp b/lib/library.cpp index dcd9dfe95..3c1eeca5b 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -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"); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 35099ca81..63c247f79 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -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"