doxygen: added more comments for CheckNullPointer and CheckUninitVar

This commit is contained in:
Daniel Marjamäki 2010-03-13 21:42:59 +01:00
parent 9b550a3f87
commit 30d3418b11
5 changed files with 89 additions and 18 deletions

View File

@ -35,7 +35,15 @@ class Tokenizer;
/// @addtogroup Checks
/// @{
/**
* @brief buffer overruns and array index out of bounds
*
* Buffer overrun and array index out of bounds are pretty much the same.
* But I generally use 'array index' if the code contains []. And the given
* index is out of bounds.
* I generally use 'buffer overrun' if you for example call a strcpy or
* other function and pass a buffer and reads or writes too much data.
*/
class CheckBufferOverrun : public Check
{
public:
@ -55,14 +63,21 @@ public:
checkBufferOverrun.bufferOverrun();
}
/** Check for buffer overruns */
/** @brief %Check for buffer overruns */
void bufferOverrun();
/**
* @brief Get minimum length of format string result
* @param input_string format string
* @param parameters given parameters to sprintf
* @return minimum length of resulting string
*/
static int countSprintfLength(const std::string &input_string, const std::list<const Token*> &parameters);
private:
/**
* Check code that matches: "sprintf ( %varid% , %str% [,)]" when varid is not 0,
* @brief %Check code that matches: "sprintf ( %varid% , %str% [,)]" when varid is not 0,
* and report found errors.
* @param tok The "sprintf" token.
* @param size The size of the buffer where sprintf is writing.

View File

@ -43,12 +43,16 @@ public:
: Check(tokenizer, settings, errorLogger)
{ }
/** @brief Run checks on the normal token list */
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
{
CheckClass checkClass(tokenizer, settings, errorLogger);
// can't be a simplified check .. the 'sizeof' is used.
checkClass.noMemset();
}
/** @brief Run checks on the simplified token list */
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
{
CheckClass checkClass(tokenizer, settings, errorLogger);
@ -78,7 +82,10 @@ public:
/**
* @brief %Check that the memsets are valid.
* The 'memset' function can do dangerous things if used wrong.
* The 'memset' function can do dangerous things if used wrong. If it
* is used on STL containers for instance it will clear all its data
* and then the STL container may leak memory or worse have an invalid state.
* It can also overwrite the virtual table.
* Important: The checking doesn't work on simplified tokens list.
*/
void noMemset();

View File

@ -27,6 +27,10 @@
/// @addtogroup Checks
/// @{
/**
* @brief Using dangerous functions that are always insecure to use.
*/
class CheckDangerousFunctions : public Check
{
public:
@ -52,9 +56,11 @@ public:
void dangerousFunctions();
private:
/** Error Messages.. */
/** Report Error : Using dangerous function 'mktemp' */
void dangerousFunctionmktemp(const Token *tok);
/** Report Error : Using dangerous function 'gets' */
void dangerousFunctiongets(const Token *tok);
/** Report Error : Using dangerous function 'scanf' */
void dangerousFunctionscanf(const Token *tok);
void getErrorMessages()

View File

@ -2683,15 +2683,16 @@ void CheckMemoryLeakStructMember::check()
/** @brief Experimental class for detecting memory leaks. The ExecutionPath functionality is used */
class CheckLocalLeaks : public ExecutionPath
{
public:
// Startup constructor
/** Startup constructor */
CheckLocalLeaks(Check *c) : ExecutionPath(c, 0), allocated(false)
{
}
/** Debugging : print checks */
static void printOut(const std::list<ExecutionPath *> &checks)
{
std::ostringstream ostr;
@ -2718,12 +2719,16 @@ private:
{
}
/** Is variable allocated? */
bool allocated;
/** Name of variable */
const std::string varname;
/* no implementation */
/** no implementation => compiler error if used */
void operator=(const CheckLocalLeaks &);
/** Allocation is detected */
static void alloc(std::list<ExecutionPath *> &checks, const unsigned int varid)
{
if (varid == 0)
@ -2738,6 +2743,7 @@ private:
}
}
/** Deallocation is detected */
static void dealloc(std::list<ExecutionPath *> &checks, const Token *tok)
{
if (tok->varId() == 0)
@ -2752,6 +2758,7 @@ private:
}
}
/** return */
static void ret(const std::list<ExecutionPath *> &checks, const Token *tok, bool &foundError)
{
std::list<ExecutionPath *>::const_iterator it;
@ -2771,6 +2778,7 @@ private:
}
}
/** parse the tokens */
const Token *parse(const Token &tok, bool &foundError, std::list<ExecutionPath *> &checks) const
{
//std::cout << "CheckLocalLeaks::parse " << tok.str() << std::endl;

View File

@ -1408,16 +1408,24 @@ static void parseFunctionCall(const Token &tok, std::list<const Token *> &var, u
}
/// @addtogroup Checks
/// @{
/**
* @brief %Check for null pointer usage (using ExecutionPath)
*/
class CheckNullpointer : public ExecutionPath
{
public:
// Startup constructor
/** Startup constructor */
CheckNullpointer(Check *c) : ExecutionPath(c, 0), null(false)
{
}
private:
// Create checking of specific variable:
/** Create checking of specific variable: */
CheckNullpointer(Check *c, const unsigned int id, const std::string &name)
: ExecutionPath(c, id),
varname(name),
@ -1425,17 +1433,22 @@ private:
{
}
/** Copy this check */
ExecutionPath *copy()
{
return new CheckNullpointer(*this);
}
/* no implementation */
/** no implementation => compiler error if used by accident */
void operator=(const CheckNullpointer &);
/** variable name for this check (empty => dummy check) */
const std::string varname;
/** is this variable null? */
bool null;
/** variable is set to null */
static void setnull(std::list<ExecutionPath *> &checks, const unsigned int varid)
{
std::list<ExecutionPath *>::iterator it;
@ -1447,6 +1460,7 @@ private:
}
}
/** variable is dereferenced. If the variable is null there's an error */
static void dereference(bool &foundError, std::list<ExecutionPath *> &checks, const Token *tok)
{
const unsigned int varid(tok->varId());
@ -1468,6 +1482,7 @@ private:
}
}
/** parse tokens */
const Token *parse(const Token &tok, bool &foundError, std::list<ExecutionPath *> &checks) const
{
if (Token::Match(tok.previous(), "[;{}] %type% * %var% ;"))
@ -1550,6 +1565,7 @@ private:
return &tok;
}
/** parse condition. @sa ExecutionPath::parseCondition */
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks)
{
if (Token::Match(&tok, "!| %var% ("))
@ -1566,38 +1582,50 @@ private:
};
/**
* @brief %Check that uninitialized variables aren't used (using ExecutionPath)
* */
class CheckUninitVar : public ExecutionPath
{
public:
// Startup constructor
/** Startup constructor */
CheckUninitVar(Check *c)
: ExecutionPath(c, 0), pointer(false), array(false), alloc(false), strncpy_(false)
{
}
private:
/** Create a copy of this check */
ExecutionPath *copy()
{
return new CheckUninitVar(*this);
}
/* no implementation */
/** no implementation => compiler error if used */
void operator=(const CheckUninitVar &);
// internal constructor for creating extra checks
/** internal constructor for creating extra checks */
CheckUninitVar(Check *c, unsigned int v, const std::string &name, bool p, bool a)
: ExecutionPath(c, v), varname(name), pointer(p), array(a), alloc(false), strncpy_(false)
{
}
/** variable name for this check */
const std::string varname;
/** is this variable a pointer? */
const bool pointer;
/** is this variable an array? */
const bool array;
/** is this variable allocated? */
bool alloc;
/** is this variable initialized with strncpy (not always zero-terminated) */
bool strncpy_;
// p = malloc ..
/** allocating pointer. For example : p = malloc(10); */
static void alloc_pointer(std::list<ExecutionPath *> &checks, unsigned int varid)
{
std::list<ExecutionPath *>::const_iterator it;
@ -1609,7 +1637,7 @@ private:
}
}
// *p = ..
/** Initializing a pointer value. For example: *p = 0; */
static void init_pointer(bool &foundError, std::list<ExecutionPath *> &checks, const Token *tok)
{
const unsigned int varid(tok->varId());
@ -1638,7 +1666,7 @@ private:
}
}
// free p;
/** Deallocate a pointer. For example: free(p); */
static void dealloc_pointer(bool &foundError, std::list<ExecutionPath *> &checks, const Token *tok)
{
const unsigned int varid(tok->varId());
@ -1825,6 +1853,7 @@ private:
use(foundError, checks, tok, 3);
}
/** declaring a variable */
void declare(std::list<ExecutionPath *> &checks, const Token *vartok, const Token &tok, const bool p, const bool a) const
{
if (vartok->varId() == 0)
@ -1868,6 +1897,7 @@ private:
checks.push_back(new CheckUninitVar(owner, vartok->varId(), vartok->str(), p, a));
}
/** parse tokens. @sa ExecutionPath::parse */
const Token *parse(const Token &tok, bool &foundError, std::list<ExecutionPath *> &checks) const
{
// Variable declaration..
@ -2210,6 +2240,7 @@ private:
public:
/** Functions that don't handle uninitialized variables well */
static std::set<std::string> uvarFunctions;
static void analyseFunctions(const Token * const tokens, std::set<std::string> &func)
@ -2254,9 +2285,13 @@ public:
}
};
/** Functions that don't handle uninitialized variables well */
std::set<std::string> CheckUninitVar::uvarFunctions;
/// @}
void CheckOther::analyseFunctions(const Token * const tokens, std::set<std::string> &func)
{
CheckUninitVar::analyseFunctions(tokens, func);