Refactoring: Removed some inconclusive checking in CheckBufferOverrun
This commit is contained in:
parent
6edb2e77b4
commit
26fab24de4
|
@ -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);
|
return;
|
||||||
else
|
|
||||||
{
|
|
||||||
_callStack.push_back(tok);
|
|
||||||
arrayIndexOutOfBounds(size, index);
|
|
||||||
_callStack.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckBufferOverrun::arrayIndexOutOfBounds(int size, int index)
|
std::ostringstream errmsg;
|
||||||
{
|
errmsg << "Array '";
|
||||||
Severity::e severity;
|
if (tok)
|
||||||
if (size <= 1 || _callStack.size() > 1)
|
errmsg << tok->str();
|
||||||
{
|
|
||||||
severity = Severity::possibleError;
|
|
||||||
if (_settings->inconclusive == false)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
errmsg << "array";
|
||||||
severity = Severity::error;
|
errmsg << "[" << size << "]' index " << index << " out of bounds";
|
||||||
}
|
reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str().c_str());
|
||||||
|
|
||||||
if (_callStack.size() == 1)
|
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Array '" << (*_callStack.begin())->str() << "[" << size << "]' index " << index << " out of bounds";
|
|
||||||
reportError(_callStack, severity, "arrayIndexOutOfBounds", oss.str().c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reportError(_callStack, severity, "arrayIndexOutOfBounds", "Array index out of bounds");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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..
|
continue;
|
||||||
if (!_settings->inconclusive)
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue