MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / checkIncorrectStringCompare

Method checkIncorrectStringCompare

lib/checkstring.cpp:275–322  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Implicit casts of string literals to bool Comparing string literal with strlen() with wrong length ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

273// Comparing string literal with strlen() with wrong length
274//---------------------------------------------------------------------------
275void 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
324void CheckStringImpl::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string)
325{

Callers 1

runChecksMethod · 0.80

Calls 10

isUsedAsBoolFunction · 0.85
isMacroUsageFunction · 0.85
nextMethod · 0.80
linkAtMethod · 0.80
endsWithFunction · 0.70
simpleMatchFunction · 0.70
isEnabledMethod · 0.45
strMethod · 0.45
tokAtMethod · 0.45
nextArgumentMethod · 0.45

Tested by

no test coverage detected