--------------------------------------------------------------------------- Implicit casts of string literals to bool Comparing string literal with strlen() with wrong length ---------------------------------------------------------------------------
| 273 | // Comparing string literal with strlen() with wrong length |
| 274 | //--------------------------------------------------------------------------- |
| 275 | void CheckStringImpl::checkIncorrectStringCompare() |
| 276 | { |
| 277 | if (!mSettings.severity.isEnabled(Severity::warning)) |
| 278 | return; |
| 279 | |
| 280 | logChecker("CheckString::checkIncorrectStringCompare"); // warning |
| 281 | |
| 282 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 283 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 284 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 285 | // skip "assert(str && ..)" and "assert(.. && str)" |
| 286 | if ((endsWith(tok->str(), "assert") || endsWith(tok->str(), "ASSERT")) && |
| 287 | Token::Match(tok, "%name% (") && |
| 288 | (Token::Match(tok->tokAt(2), "%str% &&") || Token::Match(tok->linkAt(1)->tokAt(-2), "&& %str% )"))) |
| 289 | tok = tok->linkAt(1); |
| 290 | |
| 291 | if (Token::simpleMatch(tok, ". substr (") && Token::Match(tok->tokAt(3)->nextArgument(), "%num% )")) { |
| 292 | const MathLib::biguint clen = MathLib::toBigUNumber(tok->linkAt(2)->tokAt(-1)); |
| 293 | const Token* begin = tok->previous(); |
| 294 | for (;;) { // Find start of statement |
| 295 | while (begin->link() && Token::Match(begin, "]|)|>")) |
| 296 | begin = begin->link()->previous(); |
| 297 | if (Token::Match(begin->previous(), ".|::")) |
| 298 | begin = begin->tokAt(-2); |
| 299 | else |
| 300 | break; |
| 301 | } |
| 302 | begin = begin->previous(); |
| 303 | const Token* end = tok->linkAt(2)->next(); |
| 304 | if (Token::Match(begin->previous(), "%str% ==|!=") && begin->strAt(-2) != "+") { |
| 305 | const std::size_t slen = Token::getStrLength(begin->previous()); |
| 306 | if (clen != slen) { |
| 307 | incorrectStringCompareError(tok->next(), "substr", begin->strAt(-1)); |
| 308 | } |
| 309 | } else if (Token::Match(end, "==|!= %str% !!+")) { |
| 310 | const std::size_t slen = Token::getStrLength(end->next()); |
| 311 | if (clen != slen) { |
| 312 | incorrectStringCompareError(tok->next(), "substr", end->strAt(1)); |
| 313 | } |
| 314 | } |
| 315 | } else if (Token::Match(tok, "%str%|%char%") && |
| 316 | !Token::Match(tok->next(), "%name%") && |
| 317 | isUsedAsBool(tok, mSettings) && |
| 318 | !isMacroUsage(tok)) |
| 319 | incorrectStringBooleanError(tok, tok->str()); |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | void CheckStringImpl::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string) |
| 325 | { |
no test coverage detected