Fixed #6339 (false negative: array index out of bounds on allocated buffer using valueflow)

This commit is contained in:
Daniel Marjamäki 2014-12-17 16:23:48 +01:00
parent 8728b23c6f
commit a1537e1a6e
2 changed files with 16 additions and 2 deletions

View File

@ -532,8 +532,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
}
// Array index..
if ((declarationId > 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), "%varid% [ %num% ]", declarationId))) ||
(declarationId == 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && (Token::Match(tok->next(), (varnames + " [ %num% ]").c_str()) || Token::Match(tok->next(), (varname[0] +" [ %num% ] . " + varname[1] + " [ %num% ]").c_str()))))) {
if ((declarationId > 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), "%varid% [", declarationId))) ||
(declarationId == 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && (Token::Match(tok->next(), (varnames + " [").c_str()) || Token::Match(tok->next(), (varname[0] +" [ %num% ] . " + varname[1] + " [ %num% ]").c_str()))))) {
std::vector<MathLib::bigint> indexes;
const Token *tok2 = tok->tokAt(2 + varcount);
for (; Token::Match(tok2, "[ %num% ]"); tok2 = tok2->tokAt(3)) {
@ -544,6 +544,12 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
const MathLib::bigint index = MathLib::toLongNumber(tok2->strAt(4));
indexes.push_back(index);
}
if (indexes.empty() && arrayInfo.num().size() == 1U && Token::simpleMatch(tok2, "[") && tok2->astOperand2()) {
const ValueFlow::Value *value = tok2->astOperand2()->getMaxValue(false);
if (value) {
indexes.push_back(value->intvalue);
}
}
if (indexes.size() == arrayInfo.num().size()) {
// Check if the indexes point outside the whole array..

View File

@ -438,6 +438,14 @@ private:
" str[16] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'str[16]' accessed at index 16, which is out of bounds.\n", errout.str());
check("void a(int i)\n" // valueflow
"{\n"
" char *str = new char[0x10];\n"
" str[i] = 0;\n"
"}\n"
"void b() { a(16); }");
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'str[16]' accessed at index 16, which is out of bounds.\n", errout.str());
}