BufferOverrun: negative index is out of bounds
This commit is contained in:
parent
b8b6b0ec32
commit
c666a9662b
|
@ -167,7 +167,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
if (Token::Match(tok, "%varid% [ %num% ]", varid))
|
if (Token::Match(tok, "%varid% [ %num% ]", varid))
|
||||||
{
|
{
|
||||||
int index = std::strtol(tok->strAt(2), NULL, 10);
|
int index = std::strtol(tok->strAt(2), NULL, 10);
|
||||||
if (index >= size)
|
if (index < 0 || index >= size)
|
||||||
{
|
{
|
||||||
arrayIndexOutOfBounds(tok, size, index);
|
arrayIndexOutOfBounds(tok, size, index);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
else if (Token::Match(tok, std::string(varnames + " [ %num% ]").c_str()))
|
else if (Token::Match(tok, std::string(varnames + " [ %num% ]").c_str()))
|
||||||
{
|
{
|
||||||
int index = std::strtol(tok->strAt(2 + varc), NULL, 10);
|
int index = std::strtol(tok->strAt(2 + varc), NULL, 10);
|
||||||
if (index >= size)
|
if (index < 0 || index >= size)
|
||||||
{
|
{
|
||||||
arrayIndexOutOfBounds(tok->tokAt(varc), size, index);
|
arrayIndexOutOfBounds(tok->tokAt(varc), size, index);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), "%varid% [ %num% ]", varid))
|
if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), "%varid% [ %num% ]", varid))
|
||||||
{
|
{
|
||||||
int index = std::strtol(tok->strAt(3), NULL, 10);
|
int index = std::strtol(tok->strAt(3), NULL, 10);
|
||||||
if (index >= size)
|
if (index < 0 || index >= size)
|
||||||
{
|
{
|
||||||
if (index > size || !Token::Match(tok->previous(), "& ("))
|
if (index > size || !Token::Match(tok->previous(), "& ("))
|
||||||
{
|
{
|
||||||
|
@ -215,7 +215,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), std::string(varnames + " [ %num% ]").c_str()))
|
else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), std::string(varnames + " [ %num% ]").c_str()))
|
||||||
{
|
{
|
||||||
int index = std::strtol(tok->strAt(3 + varc), NULL, 10);
|
int index = std::strtol(tok->strAt(3 + varc), NULL, 10);
|
||||||
if (index >= size)
|
if (index < 0 || index >= size)
|
||||||
{
|
{
|
||||||
arrayIndexOutOfBounds(tok->tokAt(1 + varc), size, index);
|
arrayIndexOutOfBounds(tok->tokAt(1 + varc), size, index);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
else if (tokSz->isNumber())
|
else if (tokSz->isNumber())
|
||||||
{
|
{
|
||||||
const char *num = tok->strAt(6);
|
const char *num = tok->strAt(6);
|
||||||
if (std::atoi(num) > total_size)
|
if (std::atoi(num) < 0 || std::atoi(num) > total_size)
|
||||||
{
|
{
|
||||||
bufferOverrun(tok);
|
bufferOverrun(tok);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
Token::Match(tok->next(), std::string("( %var% , " + varnames + " , %num% )").c_str()))
|
Token::Match(tok->next(), std::string("( %var% , " + varnames + " , %num% )").c_str()))
|
||||||
{
|
{
|
||||||
const char *num = tok->strAt(varc + 6);
|
const char *num = tok->strAt(varc + 6);
|
||||||
if (std::atoi(num) > total_size)
|
if (std::atoi(num) < 0 || std::atoi(num) > total_size)
|
||||||
{
|
{
|
||||||
bufferOverrun(tok);
|
bufferOverrun(tok);
|
||||||
}
|
}
|
||||||
|
|
|
@ -696,7 +696,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[])
|
||||||
// Combine "- %num%" ..
|
// Combine "- %num%" ..
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (Token::Match(tok, "[(+-*/=,] - %num%") && tok->strAt(2)[0] != '-')
|
if (Token::Match(tok, "[([+-*/=,] - %num%") && tok->strAt(2)[0] != '-')
|
||||||
{
|
{
|
||||||
tok->next()->str(std::string("-") + tok->strAt(2));
|
tok->next()->str(std::string("-") + tok->strAt(2));
|
||||||
tok->next()->deleteNext();
|
tok->next()->deleteNext();
|
||||||
|
|
|
@ -96,6 +96,7 @@ private:
|
||||||
TEST_CASE(array_index_multidim);
|
TEST_CASE(array_index_multidim);
|
||||||
TEST_CASE(array_index_switch_in_for);
|
TEST_CASE(array_index_switch_in_for);
|
||||||
TEST_CASE(array_index_calculation);
|
TEST_CASE(array_index_calculation);
|
||||||
|
TEST_CASE(array_index_negative);
|
||||||
|
|
||||||
TEST_CASE(buffer_overrun_1);
|
TEST_CASE(buffer_overrun_1);
|
||||||
TEST_CASE(buffer_overrun_2);
|
TEST_CASE(buffer_overrun_2);
|
||||||
|
@ -838,6 +839,17 @@ private:
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array index out of bounds\n", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array index out of bounds\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void array_index_negative()
|
||||||
|
{
|
||||||
|
// #948 - array index out of bound not detected 'a[-1] = 0'
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" char data[8];\n"
|
||||||
|
" data[-1] = 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'data[8]' index -1 out of bounds\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void buffer_overrun_1()
|
void buffer_overrun_1()
|
||||||
{
|
{
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
|
Loading…
Reference in New Issue