BufferOverflow: Refactoring ArrayInfo

This commit is contained in:
Daniel Marjamäki 2010-04-18 19:46:45 +02:00
parent 76a683a73a
commit 814f706329
2 changed files with 52 additions and 16 deletions

View File

@ -1286,13 +1286,14 @@ void CheckBufferOverrun::checkSprintfCall(const Token *tok, int size)
CheckBufferOverrun::ArrayInfo::ArrayInfo() CheckBufferOverrun::ArrayInfo::ArrayInfo()
: num(_num), type_size(_typesize), varname(_varname) : num(_num), type_size(_typesize), varid(_varid), varname(_varname)
{ {
_typesize = 0; _typesize = 0;
_varid = 0;
} }
CheckBufferOverrun::ArrayInfo::ArrayInfo(const CheckBufferOverrun::ArrayInfo &ai) CheckBufferOverrun::ArrayInfo::ArrayInfo(const CheckBufferOverrun::ArrayInfo &ai)
: num(_num), type_size(_typesize), varname(_varname) : num(_num), type_size(_typesize), varid(_varid), varname(_varname)
{ {
*this = ai; *this = ai;
} }
@ -1301,18 +1302,49 @@ const CheckBufferOverrun::ArrayInfo & CheckBufferOverrun::ArrayInfo::operator=(c
{ {
if (&ai != this) if (&ai != this)
{ {
_typesize = ai._typesize; _typesize = ai.type_size;
_num = ai._num; _num = ai.num;
_varname = ai._varname; _varid = ai.varid;
_varname = ai.varname;
} }
return *this; return *this;
} }
bool CheckBufferOverrun::ArrayInfo::declare(unsigned int typesize, const std::string &name, const Token *atok) bool CheckBufferOverrun::ArrayInfo::declare(const Token *tok, const Tokenizer &tokenizer)
{ {
_num.clear(); _num.clear();
_typesize = typesize; _typesize = 0;
_varname = name; _varname.clear();
if (!tok->isName())
return false;
int ivar = 0;
if (Token::Match(tok, "%type% *| %var% ["))
ivar = 1;
else if (Token::Match(tok, "%type% %type% *| %var% ["))
ivar = 2;
else
return false;
// Goto variable name token, get element size..
const Token *vartok = tok->tokAt(ivar);
if (vartok->str() == "*")
{
_typesize = tokenizer.sizeOfType(vartok);
vartok = vartok->next();
}
else
{
_typesize = tokenizer.sizeOfType(tok);
}
if (_typesize == 0)
return false;
_varname = vartok->str();
_varid = vartok->varId();
const Token *atok = vartok->tokAt(2);
if (!Token::Match(atok, "%num% ] ;|[")) if (!Token::Match(atok, "%num% ] ;|["))
return false; return false;
@ -1464,13 +1496,12 @@ void CheckBufferOverrun::executionPaths()
std::map<unsigned int, ArrayInfo> arrayInfo; std::map<unsigned int, ArrayInfo> arrayInfo;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
if (Token::Match(tok, "[;{}] %type% %var% [ %num% ]")) if (Token::Match(tok, "[;{}] %type%"))
{ {
const unsigned int varid(tok->tokAt(2)->varId());
ArrayInfo ai; ArrayInfo ai;
if (!ai.declare(_tokenizer->sizeOfType(tok->next()), tok->strAt(2), tok->tokAt(4))) if (!ai.declare(tok->next(), *_tokenizer))
continue; continue;
arrayInfo[varid] = ai; arrayInfo[ai.varid] = ai;
} }
} }

View File

@ -108,6 +108,9 @@ public:
/** size of each element in array */ /** size of each element in array */
unsigned int _typesize; unsigned int _typesize;
/** variable id */
unsigned int _varid;
/** full name of variable as pattern */ /** full name of variable as pattern */
std::string _varname; std::string _varname;
@ -118,12 +121,11 @@ public:
/** /**
* Declare array - set info * Declare array - set info
* \param typesize type size in bytes * \param tok first token in array declaration
* \param varname variable name * \param tokenizer The tokenizer (for type size)
* \param atok the index token
* \return success => true * \return success => true
*/ */
bool declare(unsigned int typesize, const std::string &varname, const Token *atok); bool declare(const Token *tok, const Tokenizer &tokenizer);
/** array size */ /** array size */
const std::vector<unsigned int> &num; const std::vector<unsigned int> &num;
@ -131,6 +133,9 @@ public:
/** type size in bytes */ /** type size in bytes */
const unsigned int &type_size; const unsigned int &type_size;
/** Variable name */
const unsigned int &varid;
/** Variable name */ /** Variable name */
const std::string &varname; const std::string &varname;
}; };