Refactoring: Removed some inconclusive checking in CheckBufferOverrun

This commit is contained in:
Daniel Marjamäki 2010-05-16 15:30:39 +02:00
parent 6edb2e77b4
commit 26fab24de4
3 changed files with 15 additions and 150 deletions

View File

@ -48,38 +48,17 @@ CheckBufferOverrun instance;
void CheckBufferOverrun::arrayIndexOutOfBounds(const Token *tok, int size, int index) void CheckBufferOverrun::arrayIndexOutOfBounds(const Token *tok, int size, int index)
{ {
if (!tok) if (size <= 1)
arrayIndexOutOfBounds(size, index);
else
{
_callStack.push_back(tok);
arrayIndexOutOfBounds(size, index);
_callStack.pop_back();
}
}
void CheckBufferOverrun::arrayIndexOutOfBounds(int size, int index)
{
Severity::e severity;
if (size <= 1 || _callStack.size() > 1)
{
severity = Severity::possibleError;
if (_settings->inconclusive == false)
return; return;
}
else
{
severity = Severity::error;
}
if (_callStack.size() == 1) std::ostringstream errmsg;
{ errmsg << "Array '";
std::ostringstream oss; if (tok)
oss << "Array '" << (*_callStack.begin())->str() << "[" << size << "]' index " << index << " out of bounds"; errmsg << tok->str();
reportError(_callStack, severity, "arrayIndexOutOfBounds", oss.str().c_str());
}
else else
reportError(_callStack, severity, "arrayIndexOutOfBounds", "Array index out of bounds"); errmsg << "array";
errmsg << "[" << size << "]' index " << index << " out of bounds";
reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str().c_str());
} }
void CheckBufferOverrun::arrayIndexOutOfBounds(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<int> &index) void CheckBufferOverrun::arrayIndexOutOfBounds(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<int> &index)
@ -103,18 +82,6 @@ void CheckBufferOverrun::arrayIndexOutOfBounds(const Token *tok, const ArrayInfo
void CheckBufferOverrun::bufferOverrun(const Token *tok, const std::string &varnames) void CheckBufferOverrun::bufferOverrun(const Token *tok, const std::string &varnames)
{ {
Severity::e severity;
if (_callStack.size() > 0)
{
severity = Severity::possibleError;
if (_settings->inconclusive == false)
return;
}
else
{
severity = Severity::error;
}
std::string v = varnames; std::string v = varnames;
while (v.find(" ") != std::string::npos) while (v.find(" ") != std::string::npos)
v.erase(v.find(" "), 1); v.erase(v.find(" "), 1);
@ -123,7 +90,7 @@ void CheckBufferOverrun::bufferOverrun(const Token *tok, const std::string &varn
if (!v.empty()) if (!v.empty())
errmsg += ": " + v; errmsg += ": " + v;
reportError(tok, severity, "bufferAccessOutOfBounds", errmsg); reportError(tok, Severity::error, "bufferAccessOutOfBounds", errmsg);
} }
void CheckBufferOverrun::dangerousStdCin(const Token *tok) void CheckBufferOverrun::dangerousStdCin(const Token *tok)
@ -746,106 +713,10 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
} }
} }
// Function call.. // Function calls not handled
// It's not interesting to check what happens when the whole struct is
// sent as the parameter, that is checked separately anyway.
if (Token::Match(tok, "%var% (")) if (Token::Match(tok, "%var% ("))
{ {
// Only perform this checking if showAll setting is enabled..
if (!_settings->inconclusive)
continue; continue;
unsigned int parlevel = 0, par = 0;
const Token * tok1 = tok;
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if (tok2->str() == "(")
{
++parlevel;
}
else if (tok2->str() == ")")
{
--parlevel;
if (parlevel < 1)
{
par = 0;
break;
}
}
else if (parlevel == 1 && (tok2->str() == ","))
{
++par;
}
if (parlevel == 1)
{
if (varid > 0 && Token::Match(tok2, "[(,] %varid% [,)]", varid))
{
++par;
tok1 = tok2->next();
break;
}
else if (varid == 0 && Token::Match(tok2, ("[(,] " + varnames + " [,)]").c_str()))
{
++par;
tok1 = tok2->tokAt(varc + 1);
break;
}
}
}
if (par == 0)
continue;
// Find function..
const Token *ftok = _tokenizer->getFunctionTokenByName(tok->str().c_str());
if (!ftok)
continue;
// Parse head of function..
ftok = ftok->tokAt(2);
parlevel = 1;
while (ftok && parlevel == 1 && par >= 1)
{
if (ftok->str() == "(")
++parlevel;
else if (ftok->str() == ")")
--parlevel;
else if (ftok->str() == ",")
--par;
else if (par == 1 && parlevel == 1 && Token::Match(ftok, "%var% [,)]"))
{
// Parameter name..
std::vector<std::string> parname;
parname.push_back(ftok->str());
const unsigned int parId = ftok->varId();
// Goto function body..
while (ftok && (ftok->str() != "{"))
ftok = ftok->next();
ftok = ftok ? ftok->next() : 0;
// Don't make recursive checking..
if (std::find_if(_callStack.begin(), _callStack.end(), TokenStrEquals(tok1->str())) != _callStack.end())
continue;
// Check variable usage in the function..
_callStack.push_back(tok1);
checkScope(ftok, parname, size, total_size, parId);
_callStack.pop_back();
// break out..
break;
}
ftok = ftok->next();
}
} }
} }
} }
@ -1245,8 +1116,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
if (total_size == 0) if (total_size == 0)
continue; continue;
// The callstack is empty
_callStack.clear();
std::vector<std::string> v; std::vector<std::string> v;
checkScope(tok->tokAt(nextTok), v, size, total_size, varid); checkScope(tok->tokAt(nextTok), v, size, total_size, varid);
} }

View File

@ -169,11 +169,7 @@ public:
*/ */
void checkFunctionCall(const Token &tok, const unsigned int par, const ArrayInfo &arrayInfo); void checkFunctionCall(const Token &tok, const unsigned int par, const ArrayInfo &arrayInfo);
/** callstack - used during intra-function checking */
std::list<const Token *> _callStack;
void arrayIndexOutOfBounds(const Token *tok, int size, int index); void arrayIndexOutOfBounds(const Token *tok, int size, int index);
void arrayIndexOutOfBounds(int size, int index);
void arrayIndexOutOfBounds(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<int> &index); void arrayIndexOutOfBounds(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<int> &index);
void bufferOverrun(const Token *tok, const std::string &varnames = ""); void bufferOverrun(const Token *tok, const std::string &varnames = "");
void dangerousStdCin(const Token *tok); void dangerousStdCin(const Token *tok);

View File

@ -431,8 +431,7 @@ private:
" struct ABC* x = (struct ABC *)malloc(sizeof(struct ABC) + 10);\n" " struct ABC* x = (struct ABC *)malloc(sizeof(struct ABC) + 10);\n"
" x->str[1] = 0;" " x->str[1] = 0;"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (possible error) Array 'str[1]' index 1 out of bounds\n", errout.str()); ASSERT_EQUALS("", errout.str());
TODO_ASSERT_EQUALS("", errout.str());
check("struct foo\n" check("struct foo\n"
"{\n" "{\n"
@ -554,7 +553,8 @@ private:
"{\n" "{\n"
" memclr(abc->str);\n" " memclr(abc->str);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:8]: (possible error) Array index out of bounds\n", errout.str()); ASSERT_EQUALS("", errout.str());
TODO_ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:8]: (possible error) Array index out of bounds\n", errout.str());
} }