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

Method invalidScanf

lib/checkio.cpp:437–482  ·  view source on GitHub ↗

--------------------------------------------------------------------------- scanf without field width limits can crash with huge input data ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

435// scanf without field width limits can crash with huge input data
436//---------------------------------------------------------------------------
437void CheckIOImpl::invalidScanf()
438{
439 if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("invalidscanf"))
440 return;
441
442 logChecker("CheckIO::invalidScanf");
443
444 const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
445 for (const Scope * scope : symbolDatabase->functionScopes) {
446 for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
447 const Token *formatToken = nullptr;
448 if (Token::Match(tok, "scanf|vscanf ( %str% ,"))
449 formatToken = tok->tokAt(2);
450 else if (Token::Match(tok, "sscanf|vsscanf|fscanf|vfscanf (")) {
451 const Token* nextArg = tok->tokAt(2)->nextArgument();
452 if (nextArg && nextArg->tokType() == Token::eString)
453 formatToken = nextArg;
454 else
455 continue;
456 } else
457 continue;
458
459 bool format = false;
460
461 // scan the string backwards, so we do not need to keep states
462 const std::string &formatstr(formatToken->str());
463 for (std::size_t i = 1; i < formatstr.length(); i++) {
464 if (formatstr[i] == '%')
465 format = !format;
466
467 else if (!format)
468 continue;
469
470 else if (std::isdigit(formatstr[i]) || formatstr[i] == '*') {
471 format = false;
472 }
473
474 else if (std::isalpha(static_cast<unsigned char>(formatstr[i])) || formatstr[i] == '[') {
475 if (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's')) // #3490 - field width limits are only necessary for string input
476 invalidScanfError(tok);
477 format = false;
478 }
479 }
480 }
481 }
482}
483
484void CheckIOImpl::invalidScanfError(const Token *tok)
485{

Callers 1

runChecksMethod · 0.80

Calls 5

isPremiumEnabledMethod · 0.80
nextMethod · 0.80
isEnabledMethod · 0.45
tokAtMethod · 0.45
nextArgumentMethod · 0.45

Tested by

no test coverage detected