Buffer overrun: Added check to detect when size argument to memset is a char constant (#213)
This commit is contained in:
parent
9f3634412e
commit
b9f4a773b8
|
@ -71,6 +71,11 @@ void CheckBufferOverrunClass::outOfBounds(const Token *tok, const std::string &w
|
||||||
reportError(tok, "error", "outOfBounds", what + " is out of bounds");
|
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, "memset|memcpy|memmove|memcmp|strncpy|fgets"))
|
||||||
{
|
{
|
||||||
if (Token::Match(tok->next(), "( %varid% , %num% , %num% )", varid) ||
|
if (Token::Match(tok->next(), "( %varid% , %any% , %any% )", varid) ||
|
||||||
Token::Match(tok->next(), "( %var% , %varid% , %num% )", varid))
|
Token::Match(tok->next(), "( %var% , %varid% , %any% )", varid))
|
||||||
{
|
{
|
||||||
const char *num = tok->strAt(6);
|
const Token *tokSz = tok->tokAt(6);
|
||||||
if (std::atoi(num) > total_size)
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ private:
|
||||||
void bufferOverrun(const Token *tok);
|
void bufferOverrun(const Token *tok);
|
||||||
void strncatUsage(const Token *tok);
|
void strncatUsage(const Token *tok);
|
||||||
void outOfBounds(const Token *tok, const std::string &what);
|
void outOfBounds(const Token *tok, const std::string &what);
|
||||||
|
void sizeArgumentAsChar(const Token *tok);
|
||||||
|
|
||||||
void getErrorMessages()
|
void getErrorMessages()
|
||||||
{
|
{
|
||||||
|
@ -79,6 +80,7 @@ private:
|
||||||
bufferOverrun(0);
|
bufferOverrun(0);
|
||||||
strncatUsage(0);
|
strncatUsage(0);
|
||||||
outOfBounds(0, "index");
|
outOfBounds(0, "index");
|
||||||
|
sizeArgumentAsChar(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,8 @@ private:
|
||||||
TEST_CASE(assign1);
|
TEST_CASE(assign1);
|
||||||
|
|
||||||
TEST_CASE(alloc); // Buffer allocated with new
|
TEST_CASE(alloc); // Buffer allocated with new
|
||||||
|
|
||||||
|
TEST_CASE(memset1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -577,6 +579,17 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:4]: (all) Array index out of bounds\n"), errout.str());
|
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)
|
REGISTER_TEST(TestBufferOverrun)
|
||||||
|
|
Loading…
Reference in New Issue