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

Method bufferOverflow

lib/checkbufferoverrun.cpp:637–692  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

635
636
637void CheckBufferOverrunImpl::bufferOverflow()
638{
639 logChecker("CheckBufferOverrun::bufferOverflow");
640
641 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
642 for (const Scope * scope : symbolDatabase->functionScopes) {
643 for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
644 if (!Token::Match(tok, "%name% (") || Token::simpleMatch(tok, ") {"))
645 continue;
646 if (!mSettings.library.hasminsize(tok))
647 continue;
648 const std::vector<const Token *> args = getArguments(tok);
649 for (int argnr = 0; argnr < args.size(); ++argnr) {
650 if (!args[argnr]->valueType() || args[argnr]->valueType()->pointer == 0)
651 continue;
652 const std::vector<Library::ArgumentChecks::MinSize> *minsizes = mSettings.library.argminsizes(tok, argnr + 1);
653 if (!minsizes || minsizes->empty())
654 continue;
655 // Get buffer size..
656 const Token *argtok = args[argnr];
657 while (argtok && argtok->isCast())
658 argtok = argtok->astOperand2() ? argtok->astOperand2() : argtok->astOperand1();
659 while (Token::Match(argtok, ".|::"))
660 argtok = argtok->astOperand2();
661 if (!argtok)
662 continue;
663 if (argtok->valueType() && argtok->valueType()->pointer == 0)
664 continue;
665 // TODO: strcpy(buf+10, "hello");
666 const ValueFlow::Value bufferSize = getBufferSize(argtok);
667 if (bufferSize.intvalue <= 0)
668 continue;
669 // buffer size == 1 => do not warn for dynamic memory
670 if (bufferSize.intvalue == 1 && Token::simpleMatch(argtok->astParent(), ".")) { // TODO: check if parent was allocated dynamically
671 const Token *tok2 = argtok;
672 while (Token::simpleMatch(tok2->astParent(), "."))
673 tok2 = tok2->astParent();
674 while (Token::Match(tok2, "[|."))
675 tok2 = tok2->astOperand1();
676 const Variable *var = tok2 ? tok2->variable() : nullptr;
677 if (var) {
678 if (var->isPointer())
679 continue;
680 if (var->isArgument() && var->isReference())
681 continue;
682 }
683 }
684 const bool error = std::none_of(minsizes->begin(), minsizes->end(), [&](const Library::ArgumentChecks::MinSize &minsize) {
685 return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings, mTokenizer);
686 });
687 if (error)
688 bufferOverflowError(args[argnr], &bufferSize, Certainty::normal);
689 }
690 }
691 }
692}
693
694void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty)

Callers 1

runChecksMethod · 0.80

Calls 14

checkBufferSizeFunction · 0.85
nextMethod · 0.80
hasminsizeMethod · 0.80
isCastMethod · 0.80
astOperand2Method · 0.80
astOperand1Method · 0.80
astParentMethod · 0.80
variableMethod · 0.80
simpleMatchFunction · 0.70
getArgumentsFunction · 0.70
sizeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected