diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 6874174f5..b6db7328b 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -26,6 +26,7 @@ #include "mathlib.h" #include "symboldatabase.h" #include "astutils.h" +#include "utils.h" #include #include @@ -77,12 +78,35 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const ArrayInfo &arrayInfo, const std::vector &index) { + bool inconclusive = false; const Token *condition = nullptr; for (std::size_t i = 0; i < index.size(); ++i) { + inconclusive |= index[i].inconclusive; if (condition == nullptr) condition = index[i].condition; } + std::list 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 (!_settings->isEnabled(Settings::WARNING)) return; @@ -100,10 +124,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra errmsg << " is out of bounds."; } - std::list callstack; - callstack.push_back(tok); - callstack.push_back(condition); - reportError(callstack, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str(), CWE119, false); + reportError(errorPath, Severity::warning, "arrayIndexOutOfBoundsCond", errmsg.str(), CWE119, inconclusive); } else { std::ostringstream errmsg; errmsg << "Array '" << arrayInfo.varname(); @@ -118,7 +139,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra errmsg << " out of bounds."; } - reportError(tok, Severity::error, "arrayIndexOutOfBounds", errmsg.str(), CWE119, false); + reportError(errorPath, Severity::error, "arrayIndexOutOfBounds", errmsg.str(), CWE119, inconclusive); } } diff --git a/lib/utils.h b/lib/utils.h index 053857fa8..221e3d124 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -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); } +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