Clarify arrayIndexOutOfBounds

This commit is contained in:
Daniel Marjamäki 2017-05-23 14:58:43 +02:00
parent a3c0eecccf
commit e73657b198
2 changed files with 37 additions and 5 deletions

View File

@ -26,6 +26,7 @@
#include "mathlib.h" #include "mathlib.h"
#include "symboldatabase.h" #include "symboldatabase.h"
#include "astutils.h" #include "astutils.h"
#include "utils.h"
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
@ -77,12 +78,35 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra
void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<ValueFlow::Value> &index) void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const ArrayInfo &arrayInfo, const std::vector<ValueFlow::Value> &index)
{ {
bool inconclusive = false;
const Token *condition = nullptr; const Token *condition = nullptr;
for (std::size_t i = 0; i < index.size(); ++i) { for (std::size_t i = 0; i < index.size(); ++i) {
inconclusive |= index[i].inconclusive;
if (condition == nullptr) if (condition == nullptr)
condition = index[i].condition; condition = index[i].condition;
} }
std::list<ErrorPathItem> errorPath;
if (_settings->xml || _settings->outputFormat == "clang" || _settings->outputFormat == "cppcheck2") {
for (std::size_t i = 0; i < index.size(); ++i) {
const ErrorPath &e = getErrorPath(tok, &index[i], "");
for (ErrorPath::const_iterator it = e.begin(); it != e.end(); ++it) {
const std::string &info = it->second;
if (info.empty())
continue;
std::string nr;
if (index.size() > 1U)
nr = "(" + MathLib::toString(i + 1) + getOrdinalText(i+1) + " array index) ";
errorPath.push_back(ErrorPathItem(it->first, nr + info));
}
}
errorPath.push_back(ErrorPathItem(tok,"Array index out of bounds"));
} else {
errorPath.push_back(ErrorPathItem(tok, "Array index out of bounds"));
if (condition)
errorPath.push_back(ErrorPathItem(condition, "Condition '" + condition->expressionString() + "'"));
}
if (condition != nullptr) { if (condition != nullptr) {
if (!_settings->isEnabled(Settings::WARNING)) if (!_settings->isEnabled(Settings::WARNING))
return; return;
@ -100,10 +124,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra
errmsg << " is out of bounds."; errmsg << " is out of bounds.";
} }
std::list<const Token *> callstack; reportError(errorPath, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str(), CWE119, inconclusive);
callstack.push_back(tok);
callstack.push_back(condition);
reportError(callstack, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str(), CWE119, false);
} else { } else {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "Array '" << arrayInfo.varname(); errmsg << "Array '" << arrayInfo.varname();
@ -118,7 +139,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra
errmsg << " out of bounds."; errmsg << " out of bounds.";
} }
reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str(), CWE119, false); reportError(errorPath, Severity::error, "arrayIndexOutOfBounds", errmsg.str(), CWE119, inconclusive);
} }
} }

View File

@ -65,4 +65,15 @@ inline bool endsWith(const std::string &str, const char end[], std::size_t endle
return (str.size() >= endlen) && (str.compare(str.size()-endlen, endlen, end)==0); return (str.size() >= endlen) && (str.compare(str.size()-endlen, endlen, end)==0);
} }
inline static const char *getOrdinalText(int i)
{
if (i == 1)
return "st";
if (i == 2)
return "nd";
if (i == 3)
return "rd";
return "th";
}
#endif #endif