| 55 | } |
| 56 | |
| 57 | std::list<const Token*> CheckNullPointerImpl::parseFunctionCall(const Token &tok, const Library &library, bool checkNullArg) |
| 58 | { |
| 59 | if (Token::Match(&tok, "%name% ( )") || !tok.tokAt(2)) |
| 60 | return {}; |
| 61 | |
| 62 | const std::vector<const Token *> args = getArguments(&tok); |
| 63 | std::list<const Token*> var; |
| 64 | for (int argnr = 1; argnr <= args.size(); ++argnr) { |
| 65 | const Token *param = args[argnr - 1]; |
| 66 | if ((!checkNullArg || library.isnullargbad(&tok, argnr)) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr)) |
| 67 | var.push_back(param); |
| 68 | else if (tok.function()) { |
| 69 | const Variable* argVar = tok.function()->getArgumentVar(argnr-1); |
| 70 | if (argVar && argVar->isStlStringType() && !argVar->isArrayOrPointer()) |
| 71 | var.push_back(param); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | if (library.formatstr_function(&tok)) { |
| 76 | const int formatStringArgNr = library.formatstr_argno(&tok); |
| 77 | if (formatStringArgNr < 0 || formatStringArgNr >= args.size()) |
| 78 | return var; |
| 79 | |
| 80 | // 1st parameter.. |
| 81 | if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && args.size() > 1 && !(args[1] && args[1]->hasKnownIntValue() && args[1]->getKnownIntValue() == 0)) // Only if length (second parameter) is not zero |
| 82 | var.push_back(args[0]); |
| 83 | |
| 84 | if (args[formatStringArgNr]->tokType() != Token::eString) |
| 85 | return var; |
| 86 | const std::string &formatString = args[formatStringArgNr]->strValue(); |
| 87 | int argnr = formatStringArgNr + 1; |
| 88 | const bool scan = library.formatstr_scan(&tok); |
| 89 | |
| 90 | bool percent = false; |
| 91 | for (auto i = formatString.cbegin(); i != formatString.cend(); ++i) { |
| 92 | if (*i == '%') { |
| 93 | percent = !percent; |
| 94 | } else if (percent) { |
| 95 | percent = false; |
| 96 | |
| 97 | bool _continue = false; |
| 98 | while (!std::isalpha(static_cast<unsigned char>(*i))) { |
| 99 | if (*i == '*') { |
| 100 | if (scan) |
| 101 | _continue = true; |
| 102 | else |
| 103 | argnr++; |
| 104 | } |
| 105 | ++i; |
| 106 | if (i == formatString.end()) |
| 107 | return var; |
| 108 | } |
| 109 | if (_continue) |
| 110 | continue; |
| 111 | |
| 112 | if (argnr < args.size() && (*i == 'n' || *i == 's' || scan)) |
| 113 | var.push_back(args[argnr]); |
| 114 |
nothing calls this directly
no test coverage detected