Buffer overrun: Added check to detect when size argument to memset is a char constant (#213)

This commit is contained in:
Daniel Marjamäki 2009-03-25 07:25:10 +01:00
parent 9f3634412e
commit b9f4a773b8
3 changed files with 31 additions and 5 deletions

View File

@ -71,6 +71,11 @@ void CheckBufferOverrunClass::outOfBounds(const Token *tok, const std::string &w
reportError(tok, "error", "outOfBounds", what + " is out of bounds");
}
void CheckBufferOverrunClass::sizeArgumentAsChar(const Token *tok)
{
reportError(tok, "all", "sizeArgumentAsChar", "The size argument is given as a char constant");
}
//---------------------------------------------------------------------------
@ -163,13 +168,19 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
{
if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets"))
{
if (Token::Match(tok->next(), "( %varid% , %num% , %num% )", varid) ||
Token::Match(tok->next(), "( %var% , %varid% , %num% )", varid))
if (Token::Match(tok->next(), "( %varid% , %any% , %any% )", varid) ||
Token::Match(tok->next(), "( %var% , %varid% , %any% )", varid))
{
const char *num = tok->strAt(6);
if (std::atoi(num) > total_size)
const Token *tokSz = tok->tokAt(6);
if (tokSz->str()[0] == '\'')
sizeArgumentAsChar(tok);
else if (tokSz->isNumber())
{
bufferOverrun(tok);
const char *num = tok->strAt(6);
if (std::atoi(num) > total_size)
{
bufferOverrun(tok);
}
}
}
}

View File

@ -72,6 +72,7 @@ private:
void bufferOverrun(const Token *tok);
void strncatUsage(const Token *tok);
void outOfBounds(const Token *tok, const std::string &what);
void sizeArgumentAsChar(const Token *tok);
void getErrorMessages()
{
@ -79,6 +80,7 @@ private:
bufferOverrun(0);
strncatUsage(0);
outOfBounds(0, "index");
sizeArgumentAsChar(0);
}
};

View File

@ -104,6 +104,8 @@ private:
TEST_CASE(assign1);
TEST_CASE(alloc); // Buffer allocated with new
TEST_CASE(memset1);
}
@ -577,6 +579,17 @@ private:
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: (all) Array index out of bounds\n"), errout.str());
}
void memset1()
{
check("void foo()\n"
"{\n"
" char s[10];\n"
" memset(s, 5, '*');\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:4]: (all) The size argument is given as a char constant\n"), errout.str());
}
};
REGISTER_TEST(TestBufferOverrun)