Refactoring of Null Pointer Checker
This commit is contained in:
parent
d0c1632b51
commit
87fe5c060e
|
@ -61,17 +61,17 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
if (Token::Match(&tok, "%name% ( )") || !tok.tokAt(2))
|
if (Token::Match(&tok, "%name% ( )") || !tok.tokAt(2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Token* firstParam = tok.tokAt(2);
|
const std::vector<const Token *> args = getArguments(&tok);
|
||||||
const Token* secondParam = firstParam->nextArgument();
|
const Token* firstParam = args.size() > 0 ? args[0] : nullptr;
|
||||||
|
const Token* secondParam = args.size() > 1 ? args[1] : nullptr;
|
||||||
|
|
||||||
// 1st parameter..
|
// 1st parameter..
|
||||||
if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "0") // Only if length (second parameter) is not zero
|
if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "0") // Only if length (second parameter) is not zero
|
||||||
var.push_back(firstParam);
|
var.push_back(firstParam);
|
||||||
|
|
||||||
if (library || tok.function() != nullptr) {
|
if (library || tok.function() != nullptr) {
|
||||||
const Token *param = firstParam;
|
for (int argnr = 1; argnr <= args.size(); ++argnr) {
|
||||||
int argnr = 1;
|
const Token *param = args[argnr - 1];
|
||||||
while (param) {
|
|
||||||
if (library && library->isnullargbad(&tok, argnr) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr))
|
if (library && library->isnullargbad(&tok, argnr) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr))
|
||||||
var.push_back(param);
|
var.push_back(param);
|
||||||
else if (tok.function()) {
|
else if (tok.function()) {
|
||||||
|
@ -79,65 +79,58 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
if (argVar && argVar->isStlStringType() && !argVar->isArrayOrPointer())
|
if (argVar && argVar->isStlStringType() && !argVar->isArrayOrPointer())
|
||||||
var.push_back(param);
|
var.push_back(param);
|
||||||
}
|
}
|
||||||
param = param->nextArgument();
|
|
||||||
argnr++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf|wprintf|swprintf|fwprintf|wscanf|swscanf|fwscanf")) {
|
if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf|wprintf|swprintf|fwprintf|wscanf|swscanf|fwscanf")) {
|
||||||
const Token* argListTok = nullptr; // Points to first va_list argument
|
|
||||||
std::string formatString;
|
std::string formatString;
|
||||||
|
int argnr = args.size();
|
||||||
const bool scan = Token::Match(&tok, "scanf|sscanf|fscanf|wscanf|swscanf|fwscanf");
|
const bool scan = Token::Match(&tok, "scanf|sscanf|fscanf|wscanf|swscanf|fwscanf");
|
||||||
|
|
||||||
if (Token::Match(&tok, "printf|scanf|wprintf|wscanf ( %str%")) {
|
if (Token::Match(&tok, "printf|scanf|wprintf|wscanf ( %str%")) {
|
||||||
formatString = firstParam->strValue();
|
formatString = firstParam->strValue();
|
||||||
argListTok = secondParam;
|
argnr = 1;
|
||||||
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf|fwprintf|fwscanf|swscanf")) {
|
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf|fwprintf|fwscanf|swscanf")) {
|
||||||
const Token* formatStringTok = secondParam; // Find second parameter (format string)
|
const Token* formatStringTok = secondParam; // Find second parameter (format string)
|
||||||
if (formatStringTok && formatStringTok->tokType() == Token::eString) {
|
if (formatStringTok && formatStringTok->tokType() == Token::eString) {
|
||||||
argListTok = formatStringTok->nextArgument(); // Find third parameter (first argument of va_args)
|
argnr = 2; // third parameter (first argument of va_args)
|
||||||
formatString = formatStringTok->strValue();
|
formatString = formatStringTok->strValue();
|
||||||
}
|
}
|
||||||
} else if (Token::Match(&tok, "snprintf|fnprintf|swprintf") && secondParam) {
|
} else if (Token::Match(&tok, "snprintf|fnprintf|swprintf") && secondParam) {
|
||||||
const Token* formatStringTok = secondParam->nextArgument(); // Find third parameter (format string)
|
const Token* formatStringTok = args.size() > 2 ? args[2] : nullptr; // third parameter (format string)
|
||||||
if (formatStringTok && formatStringTok->tokType() == Token::eString) {
|
if (formatStringTok && formatStringTok->tokType() == Token::eString) {
|
||||||
argListTok = formatStringTok->nextArgument(); // Find fourth parameter (first argument of va_args)
|
argnr = 3; // fourth parameter (first argument of va_args)
|
||||||
formatString = formatStringTok->strValue();
|
formatString = formatStringTok->strValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argListTok) {
|
bool percent = false;
|
||||||
bool percent = false;
|
for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i) {
|
||||||
for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i) {
|
if (*i == '%') {
|
||||||
if (*i == '%') {
|
percent = !percent;
|
||||||
percent = !percent;
|
} else if (percent) {
|
||||||
} else if (percent) {
|
percent = false;
|
||||||
percent = false;
|
|
||||||
|
|
||||||
bool _continue = false;
|
bool _continue = false;
|
||||||
while (!std::isalpha((unsigned char)*i)) {
|
while (!std::isalpha((unsigned char)*i)) {
|
||||||
if (*i == '*') {
|
if (*i == '*') {
|
||||||
if (scan)
|
if (scan)
|
||||||
_continue = true;
|
_continue = true;
|
||||||
else
|
else
|
||||||
argListTok = argListTok->nextArgument();
|
argnr++;
|
||||||
}
|
|
||||||
++i;
|
|
||||||
if (!argListTok || i == formatString.end())
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (_continue)
|
++i;
|
||||||
continue;
|
if (i == formatString.end())
|
||||||
|
return;
|
||||||
if ((*i == 'n' || *i == 's' || scan)) {
|
|
||||||
var.push_back(argListTok);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*i != 'm') // %m is a non-standard glibc extension that requires no parameter
|
|
||||||
argListTok = argListTok->nextArgument(); // Find next argument
|
|
||||||
if (!argListTok)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (_continue)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (argnr < args.size() && (*i == 'n' || *i == 's' || scan))
|
||||||
|
var.push_back(args[argnr]);
|
||||||
|
|
||||||
|
if (*i != 'm') // %m is a non-standard glibc extension that requires no parameter
|
||||||
|
argnr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,9 +416,8 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
|
|
||||||
// is one of the var items a NULL pointer?
|
// is one of the var items a NULL pointer?
|
||||||
for (const Token *vartok : var) {
|
for (const Token *vartok : var) {
|
||||||
if (Token::Match(vartok, "0|NULL|nullptr [,)]")) {
|
if (vartok->hasKnownIntValue() && vartok->getKnownIntValue() == 0)
|
||||||
nullPointerError(vartok);
|
nullPointerError(vartok);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Token::Match(tok, "std :: string|wstring ( 0|NULL|nullptr )"))
|
} else if (Token::Match(tok, "std :: string|wstring ( 0|NULL|nullptr )"))
|
||||||
|
|
|
@ -52,9 +52,9 @@ void validGuiCode()
|
||||||
|
|
||||||
void nullPointer(const wxString &str)
|
void nullPointer(const wxString &str)
|
||||||
{
|
{
|
||||||
// TODO cppcheck-suppress nullPointer
|
// cppcheck-suppress nullPointer
|
||||||
wxLogGeneric(wxLOG_Message, (char*)NULL);
|
wxLogGeneric(wxLOG_Message, (char*)NULL);
|
||||||
// TODO cppcheck-suppress nullPointer
|
// cppcheck-suppress nullPointer
|
||||||
wxLogMessage((char*)NULL);
|
wxLogMessage((char*)NULL);
|
||||||
|
|
||||||
double *doublePtr = NULL;
|
double *doublePtr = NULL;
|
||||||
|
|
Loading…
Reference in New Issue