warn when buffer is not zero terminated after memcpy

This commit is contained in:
Robert Reif 2011-09-05 15:41:37 -04:00
parent 3c8988e7a5
commit f5d71d1ac5
3 changed files with 22 additions and 2 deletions

View File

@ -178,6 +178,12 @@ void CheckBufferOverrun::cmdLineArgsError(const Token *tok)
reportError(tok, Severity::error, "insecureCmdLineArgs", "Buffer overrun possible for long cmd-line args"); reportError(tok, Severity::error, "insecureCmdLineArgs", "Buffer overrun possible for long cmd-line args");
} }
void CheckBufferOverrun::terminateMemcpyError(const Token *tok, const std::string &varname)
{
reportError(tok, Severity::warning, "terminateMemcpy",
"The buffer '" + varname + "' is not zero-terminated after the call to memcpy().\n"
"This will cause bugs later in the code if the code assumes buffer is zero-terminated.");
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1228,13 +1234,18 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
checkFunctionCall(tok, arrayInfo); checkFunctionCall(tok, arrayInfo);
} }
if (Token::Match(tok, "strncpy ( %varid% , %str% , %num% )", arrayInfo.varid())) if (Token::Match(tok, "strncpy|memcpy ( %varid% , %str% , %num% )", arrayInfo.varid()))
{ {
unsigned int num = (unsigned int)MathLib::toLongNumber(tok->strAt(6)); unsigned int num = (unsigned int)MathLib::toLongNumber(tok->strAt(6));
if (Token::getStrLength(tok->tokAt(4)) >= total_size && total_size == num) if (Token::getStrLength(tok->tokAt(4)) >= total_size && total_size == num)
{ {
if (_settings->inconclusive) if (_settings->inconclusive)
{
if (tok->str() == "strncpy")
terminateStrncpyError(tok, tok->strAt(2), true); terminateStrncpyError(tok, tok->strAt(2), true);
else
terminateMemcpyError(tok, tok->strAt(2));
}
} }
} }

View File

@ -217,6 +217,7 @@ public:
void outOfBoundsError(const Token *tok, const std::string &what); void outOfBoundsError(const Token *tok, const std::string &what);
void sizeArgumentAsCharError(const Token *tok); void sizeArgumentAsCharError(const Token *tok);
void terminateStrncpyError(const Token *tok, const std::string &varname, bool conclusive); void terminateStrncpyError(const Token *tok, const std::string &varname, bool conclusive);
void terminateMemcpyError(const Token *tok, const std::string &varname);
void negativeIndexError(const Token *tok, MathLib::bigint index); void negativeIndexError(const Token *tok, MathLib::bigint index);
void cmdLineArgsError(const Token *tok); void cmdLineArgsError(const Token *tok);
void pointerOutOfBoundsError(const Token *tok, const std::string &object); // UB when result of calculation is out of bounds void pointerOutOfBoundsError(const Token *tok, const std::string &object); // UB when result of calculation is out of bounds
@ -232,6 +233,7 @@ public:
c.outOfBoundsError(0, "index"); c.outOfBoundsError(0, "index");
c.sizeArgumentAsCharError(0); c.sizeArgumentAsCharError(0);
c.terminateStrncpyError(0, "buffer", false); c.terminateStrncpyError(0, "buffer", false);
c.terminateMemcpyError(0, "buffer");
c.negativeIndexError(0, -1); c.negativeIndexError(0, -1);
c.cmdLineArgsError(0); c.cmdLineArgsError(0);
c.pointerOutOfBoundsError(0, "array"); c.pointerOutOfBoundsError(0, "array");

View File

@ -2583,6 +2583,13 @@ private:
" memchr(a, b, 10);\n" " memchr(a, b, 10);\n"
"}\n"); "}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", "", errout.str()); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", "", errout.str());
check("void f()\n"
"{\n"
" char c[6];\n"
" memcpy(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to memcpy().\n", errout.str());
} }
// ticket #2121 - buffer access out of bounds when using uint32_t // ticket #2121 - buffer access out of bounds when using uint32_t