Refactoring of Null Pointer Checker

This commit is contained in:
Daniel Marjamäki 2019-03-16 21:21:30 +01:00
parent d0c1632b51
commit 87fe5c060e
2 changed files with 37 additions and 45 deletions

View File

@ -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 )"))

View File

@ -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;