warn when buffer is not zero terminated after strncpy
This commit is contained in:
parent
2601733ff7
commit
3c8988e7a5
|
@ -155,8 +155,15 @@ void CheckBufferOverrun::sizeArgumentAsCharError(const Token *tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::string &varname)
|
void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::string &varname, bool conclusive)
|
||||||
{
|
{
|
||||||
|
if (conclusive)
|
||||||
|
reportError(tok, Severity::warning, "terminateStrncpy",
|
||||||
|
"The buffer '" + varname + "' is not zero-terminated after the call to strncpy().\n"
|
||||||
|
"The use of strncpy() usually indicates that the programmer wants to ensure "
|
||||||
|
"the buffer is zero-terminated after the call. This will cause bugs later in the code if "
|
||||||
|
"the code assumes buffer is zero-terminated.");
|
||||||
|
else
|
||||||
reportError(tok, Severity::warning, "terminateStrncpy",
|
reportError(tok, Severity::warning, "terminateStrncpy",
|
||||||
"The buffer '" + varname + "' may not be zero-terminated after the call to strncpy().\n"
|
"The buffer '" + varname + "' may not be zero-terminated after the call to strncpy().\n"
|
||||||
"The use of strncpy() usually indicates that the programmer wants to ensure "
|
"The use of strncpy() usually indicates that the programmer wants to ensure "
|
||||||
|
@ -1221,6 +1228,16 @@ 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()))
|
||||||
|
{
|
||||||
|
unsigned int num = (unsigned int)MathLib::toLongNumber(tok->strAt(6));
|
||||||
|
if (Token::getStrLength(tok->tokAt(4)) >= total_size && total_size == num)
|
||||||
|
{
|
||||||
|
if (_settings->inconclusive)
|
||||||
|
terminateStrncpyError(tok, tok->strAt(2), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((Token::Match(tok, "strncpy|strncat ( %varid% , %var% , %num% )", arrayInfo.varid())) ||
|
if ((Token::Match(tok, "strncpy|strncat ( %varid% , %var% , %num% )", arrayInfo.varid())) ||
|
||||||
(Token::Match(tok, "strncpy|strncat ( %varid% , %var% [ %any% ] , %num% )", arrayInfo.varid())))
|
(Token::Match(tok, "strncpy|strncat ( %varid% , %var% [ %any% ] , %num% )", arrayInfo.varid())))
|
||||||
{
|
{
|
||||||
|
@ -1243,7 +1260,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
||||||
{
|
{
|
||||||
// this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3
|
// this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3
|
||||||
if (_settings->isEnabled("style") && _settings->inconclusive)
|
if (_settings->isEnabled("style") && _settings->inconclusive)
|
||||||
terminateStrncpyError(tok, tok->strAt(2));
|
terminateStrncpyError(tok, tok->strAt(2), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -216,7 +216,7 @@ public:
|
||||||
void strncatUsageError(const Token *tok);
|
void strncatUsageError(const Token *tok);
|
||||||
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);
|
void terminateStrncpyError(const Token *tok, const std::string &varname, bool conclusive);
|
||||||
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
|
||||||
|
@ -231,7 +231,7 @@ public:
|
||||||
c.strncatUsageError(0);
|
c.strncatUsageError(0);
|
||||||
c.outOfBoundsError(0, "index");
|
c.outOfBoundsError(0, "index");
|
||||||
c.sizeArgumentAsCharError(0);
|
c.sizeArgumentAsCharError(0);
|
||||||
c.terminateStrncpyError(0, "buffer");
|
c.terminateStrncpyError(0, "buffer", false);
|
||||||
c.negativeIndexError(0, -1);
|
c.negativeIndexError(0, -1);
|
||||||
c.cmdLineArgsError(0);
|
c.cmdLineArgsError(0);
|
||||||
c.pointerOutOfBoundsError(0, "array");
|
c.pointerOutOfBoundsError(0, "array");
|
||||||
|
|
|
@ -2908,7 +2908,7 @@ private:
|
||||||
" char c[6];\n"
|
" char c[6];\n"
|
||||||
" strncpy(c,\"hello!\",sizeof(c));\n"
|
" strncpy(c,\"hello!\",sizeof(c));\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to strncpy().\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue