buffer overrun: Added checking of strncat

This commit is contained in:
Daniel Marjamäki 2009-02-20 21:00:59 +00:00
parent 0e1ef1f45f
commit 15e86db3ed
4 changed files with 23 additions and 3 deletions

View File

@ -239,7 +239,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
// Writing data into array.. // Writing data into array..
if (Token::Match(tok, std::string("strcpy ( " + varnames + " , %str% )").c_str())) if (Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %str% )").c_str()))
{ {
int len = 0; int len = 0;
const char *str = tok->strAt(varc + 4); const char *str = tok->strAt(varc + 4);
@ -256,6 +256,16 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
} }
continue; continue;
} }
// Dangerous usage of strncat..
if (Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid))
{
int n = atoi(tok->strAt(6));
if (n == size)
_errorLogger->strncatUsage(_tokenizer, tok);
}
// sprintf.. // sprintf..
if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% ,", varid)) if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% ,", varid))

View File

@ -110,6 +110,15 @@ public:
return s._showAll; return s._showAll;
} }
void strncatUsage(const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(tokenizer, Location, "all", "Dangerous usage of strncat, possible buffer overrun", "strncatUsage");
}
static bool strncatUsage(const Settings &s)
{
return s._showAll;
}
void outOfBounds(const Tokenizer *tokenizer, const Token *Location, const std::string &what) void outOfBounds(const Tokenizer *tokenizer, const Token *Location, const std::string &what)
{ {
_writemsg(tokenizer, Location, "error", "" + what + " is out of bounds", "outOfBounds"); _writemsg(tokenizer, Location, "error", "" + what + " is out of bounds", "outOfBounds");

View File

@ -93,7 +93,7 @@ private:
TEST_CASE(snprintf3); TEST_CASE(snprintf3);
// TODO TEST_CASE(strncat1); // TODO TEST_CASE(strncat1);
// TODO TEST_CASE(strncat2); TEST_CASE(strncat2);
TEST_CASE(varid1); TEST_CASE(varid1);
TEST_CASE(varid2); TEST_CASE(varid2);
@ -487,7 +487,7 @@ private:
" char str[5];\n" " char str[5];\n"
" strncat(str, a, 5);\n" " strncat(str, a, 5);\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: (error) dangerous usage of strncat. If str is nonempty there will be a buffer overrun\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:4]: (all) Dangerous usage of strncat, possible buffer overrun\n"), errout.str());
} }

View File

@ -60,6 +60,7 @@ int main()
// checkbufferoverrun.cpp // checkbufferoverrun.cpp
err.push_back(Message("arrayIndexOutOfBounds", Message::all, "Array index out of bounds")); err.push_back(Message("arrayIndexOutOfBounds", Message::all, "Array index out of bounds"));
err.push_back(Message("bufferOverrun", Message::all, "Buffer overrun")); err.push_back(Message("bufferOverrun", Message::all, "Buffer overrun"));
err.push_back(Message("strncatUsage", Message::all, "Dangerous usage of strncat, possible buffer overrun"));
err.push_back(Message("outOfBounds", Message::error, "%1 is out of bounds", "what")); err.push_back(Message("outOfBounds", Message::error, "%1 is out of bounds", "what"));
err.push_back(Message("stlOutOfBounds", Message::error, "%1 is out of bounds", "what")); err.push_back(Message("stlOutOfBounds", Message::error, "%1 is out of bounds", "what"));