errmsg: Added error messages for "Array index out of bounds" and "Buffer overrun"

This commit is contained in:
Daniel Marjamäki 2009-01-10 19:23:21 +00:00
parent 897c02e3ed
commit 47a7c915fa
6 changed files with 39 additions and 14 deletions

View File

@ -86,7 +86,7 @@ install: cppcheck
###### Build ###### Build
src/checkbufferoverrun.o: src/checkbufferoverrun.cpp src/checkbufferoverrun.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/checkbufferoverrun.o: src/checkbufferoverrun.cpp src/checkbufferoverrun.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/errormessage.h
g++ $(CXXFLAGS) -c -o src/checkbufferoverrun.o src/checkbufferoverrun.cpp g++ $(CXXFLAGS) -c -o src/checkbufferoverrun.o src/checkbufferoverrun.cpp
src/checkclass.o: src/checkclass.cpp src/checkclass.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/errormessage.h src/checkclass.o: src/checkclass.cpp src/checkclass.h src/tokenize.h src/settings.h src/errorlogger.h src/token.h src/errormessage.h

View File

@ -21,6 +21,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "checkbufferoverrun.h" #include "checkbufferoverrun.h"
#include "errormessage.h"
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
@ -48,13 +49,13 @@ CheckBufferOverrunClass::~CheckBufferOverrunClass()
} }
// Modified version of 'ReportError' that also reports the callstack // Modified version of 'ReportError' that also reports the callstack
void CheckBufferOverrunClass::ReportError(const Token *tok, const char errmsg[]) void CheckBufferOverrunClass::ReportError(const std::string &errmsg)
{ {
std::ostringstream ostr; std::ostringstream ostr;
std::list<const Token *>::const_iterator it; std::list<const Token *>::const_iterator it;
for (it = _callStack.begin(); it != _callStack.end(); it++) for (it = _callStack.begin(); it != _callStack.end(); it++)
ostr << _tokenizer->fileLine(*it) << " -> "; ostr << _tokenizer->fileLine(*it) << " -> ";
ostr << _tokenizer->fileLine(tok) << ": " << errmsg; ostr << errmsg;
_errorLogger->reportErr(ostr.str()); _errorLogger->reportErr(ostr.str());
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -92,7 +93,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(2); const char *num = tok->strAt(2);
if (strtol(num, NULL, 10) >= size) if (strtol(num, NULL, 10) >= size)
{ {
ReportError(tok->next(), "Array index out of bounds"); ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
} }
} }
} }
@ -101,7 +102,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(2 + varc); const char *num = tok->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size) if (strtol(num, NULL, 10) >= size)
{ {
ReportError(tok->next(), "Array index out of bounds"); ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
} }
} }
@ -129,7 +130,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(3); const char *num = tok->strAt(3);
if (strtol(num, NULL, 10) >= size) if (strtol(num, NULL, 10) >= size)
{ {
ReportError(tok->next(), "Array index out of bounds"); ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
} }
} }
} }
@ -138,7 +139,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->next()->strAt(2 + varc); const char *num = tok->next()->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size) if (strtol(num, NULL, 10) >= size)
{ {
ReportError(tok->next(), "Array index out of bounds"); ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
} }
tok = tok->tokAt(4); tok = tok->tokAt(4);
continue; continue;
@ -156,7 +157,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(6); const char *num = tok->strAt(6);
if (atoi(num) > total_size) if (atoi(num) > total_size)
{ {
ReportError(tok, "Buffer overrun"); ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
} }
} }
continue; continue;
@ -170,7 +171,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(varc + 6); const char *num = tok->strAt(varc + 6);
if (atoi(num) > total_size) if (atoi(num) > total_size)
{ {
ReportError(tok, "Buffer overrun"); ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
} }
} }
continue; continue;
@ -229,7 +230,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
if (Token::Match(tok2, pattern.str().c_str())) if (Token::Match(tok2, pattern.str().c_str()))
{ {
ReportError(tok2, "Buffer overrun"); ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok2));
break; break;
} }
@ -252,7 +253,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
} }
if (len > 2 && len >= (int)size + 2) if (len > 2 && len >= (int)size + 2)
{ {
ReportError(tok, "Buffer overrun"); ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
} }
continue; continue;
} }

View File

@ -41,7 +41,7 @@ private:
void CheckBufferOverrun_StructVariable(); void CheckBufferOverrun_StructVariable();
void CheckBufferOverrun_LocalVariable(); void CheckBufferOverrun_LocalVariable();
void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid); void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid);
void ReportError(const Token *tok, const char errmsg[]); void ReportError(const std::string &errmsg);
const Tokenizer *_tokenizer; const Tokenizer *_tokenizer;
const Settings _settings; const Settings _settings;

View File

@ -279,10 +279,12 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
if (ErrorMessage::virtualDestructor(_settings)) if (ErrorMessage::virtualDestructor(_settings))
checkClass.virtualDestructor(); checkClass.virtualDestructor();
// Array index out of bounds / Buffer overruns..
if (ErrorMessage::arrayIndexOutOfBounds(_settings) && ErrorMessage::bufferOverrun(_settings))
checkBufferOverrun.bufferOverrun();
if (_settings._showAll) if (_settings._showAll)
{ {
// Buffer overruns..
checkBufferOverrun.bufferOverrun();
// Check for "if (a=b)" // Check for "if (a=b)"
checkOther.CheckIfAssignment(); checkOther.CheckIfAssignment();

View File

@ -30,6 +30,24 @@ private:
ErrorMessage() { } ErrorMessage() { }
static std::string msg1(const Tokenizer *tokenizer, const Token *Location); static std::string msg1(const Tokenizer *tokenizer, const Token *Location);
public: public:
static std::string arrayIndexOutOfBounds(const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + "Array index out of bounds";
}
static bool arrayIndexOutOfBounds(const Settings &s)
{
return s._showAll;
}
static std::string bufferOverrun(const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + "Buffer overrun";
}
static bool bufferOverrun(const Settings &s)
{
return s._showAll;
}
static std::string noConstructor(const Tokenizer *tokenizer, const Token *Location, const std::string &classname) static std::string noConstructor(const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
{ {
return msg1(tokenizer, Location) + "The class '" + classname + "' has no constructor"; return msg1(tokenizer, Location) + "The class '" + classname + "' has no constructor";

View File

@ -53,6 +53,10 @@ int main()
// Error messages.. // Error messages..
std::list<Message> err; std::list<Message> err;
// checkbufferoverrun.cpp
err.push_back(Message("arrayIndexOutOfBounds", Message::ALL, "Array index out of bounds"));
err.push_back(Message("bufferOverrun", Message::ALL, "Buffer overrun"));
// checkclass.cpp.. // checkclass.cpp..
err.push_back(Message("noConstructor", Message::STYLE, "The class '%1' has no constructor", "classname")); err.push_back(Message("noConstructor", Message::STYLE, "The class '%1' has no constructor", "classname"));
err.push_back(Message("uninitVar", 0, "Uninitialized member variable '%1::%2'", "classname", "varname")); err.push_back(Message("uninitVar", 0, "Uninitialized member variable '%1::%2'", "classname", "varname"));