@@ -620,19 +620,19 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
620620}
621621// ---------------------------------------------------------------------------
622622
623- static bool checkBufferSize (const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector<const Token *> &args, const MathLib::bigint bufferSize, const Settings &settings, const Tokenizer* tokenizer)
623+ static bool checkBufferSize (const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector<const Token *> &args, ValueFlow::Value& bufferSize, const Settings &settings, const Tokenizer* tokenizer)
624624{
625625 const Token * const arg = (minsize.arg > 0 && minsize.arg - 1 < args.size ()) ? args[minsize.arg - 1 ] : nullptr ;
626626 const Token * const arg2 = (minsize.arg2 > 0 && minsize.arg2 - 1 < args.size ()) ? args[minsize.arg2 - 1 ] : nullptr ;
627627
628628 switch (minsize.type ) {
629629 case Library::ArgumentChecks::MinSize::Type::STRLEN :
630630 if (settings.library .isargformatstr (ftok, minsize.arg )) {
631- return getMinFormatStringOutputLength (args, minsize.arg , settings) < bufferSize;
631+ return getMinFormatStringOutputLength (args, minsize.arg , settings) < bufferSize. intvalue ;
632632 } else if (arg) {
633633 const Token *strtoken = arg->getValueTokenMaxStrLength ();
634634 if (strtoken)
635- return Token::getStrLength (strtoken) < bufferSize;
635+ return Token::getStrLength (strtoken) < bufferSize. intvalue ;
636636 }
637637 break ;
638638 case Library::ArgumentChecks::MinSize::Type::ARGVALUE : {
@@ -641,7 +641,14 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi
641641 const int baseSize = tokenizer->sizeOfType (minsize.baseType );
642642 if (baseSize != 0 )
643643 myMinsize *= baseSize;
644- return myMinsize <= bufferSize;
644+ const bool ok = myMinsize <= bufferSize.intvalue ;
645+ if (!ok) {
646+ if (bufferSize.errorPath .empty ())
647+ bufferSize.errorPath = arg->values ().front ().errorPath ;
648+ if (!bufferSize.condition )
649+ bufferSize.condition = arg->values ().front ().condition ;
650+ }
651+ return ok;
645652 }
646653 break ;
647654 }
@@ -650,14 +657,14 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi
650657 break ;
651658 case Library::ArgumentChecks::MinSize::Type::MUL :
652659 if (arg && arg2 && arg->hasKnownIntValue () && arg2->hasKnownIntValue ())
653- return (arg->getKnownIntValue () * arg2->getKnownIntValue ()) <= bufferSize;
660+ return (arg->getKnownIntValue () * arg2->getKnownIntValue ()) <= bufferSize. intvalue ;
654661 break ;
655662 case Library::ArgumentChecks::MinSize::Type::VALUE : {
656663 MathLib::bigint myMinsize = minsize.value ;
657664 const int baseSize = tokenizer->sizeOfType (minsize.baseType );
658665 if (baseSize != 0 )
659666 myMinsize *= baseSize;
660- return myMinsize <= bufferSize;
667+ return myMinsize <= bufferSize. intvalue ;
661668 }
662669 case Library::ArgumentChecks::MinSize::Type::NONE :
663670 break ;
@@ -695,7 +702,7 @@ void CheckBufferOverrunImpl::bufferOverflow()
695702 if (argtok->valueType () && argtok->valueType ()->pointer == 0 )
696703 continue ;
697704 // TODO: strcpy(buf+10, "hello");
698- const ValueFlow::Value bufferSize = getBufferSize (argtok, mSettings );
705+ ValueFlow::Value bufferSize = getBufferSize (argtok, mSettings );
699706 if (bufferSize.intvalue <= 0 )
700707 continue ;
701708 // buffer size == 1 => do not warn for dynamic memory
@@ -714,7 +721,7 @@ void CheckBufferOverrunImpl::bufferOverflow()
714721 }
715722 }
716723 const bool error = std::none_of (minsizes->begin (), minsizes->end (), [&](const Library::ArgumentChecks::MinSize &minsize) {
717- return checkBufferSize (tok, minsize, args, bufferSize. intvalue , mSettings , mTokenizer );
724+ return checkBufferSize (tok, minsize, args, bufferSize, mSettings , mTokenizer );
718725 });
719726 if (error)
720727 bufferOverflowError (args[argnr], &bufferSize, Certainty::normal);
@@ -726,7 +733,7 @@ void CheckBufferOverrunImpl::bufferOverflow()
726733void CheckBufferOverrunImpl::bufferOverflowError (const Token *tok, const ValueFlow::Value *value, Certainty certainty)
727734{
728735 const auto errorPath = getErrorPath (tok, value, " Buffer overrun" );
729- const auto severity = !value || value->isKnown () ? Severity::error : Severity::warning;
736+ const auto severity = !value || ( value->isKnown () && !value-> condition ) ? Severity::error : Severity::warning;
730737 const std::string msg = " Buffer is accessed out of bounds: " + (tok ? getRealBufferTok (tok)->expressionString () : " buf" );
731738 reportError (errorPath, severity, " bufferAccessOutOfBounds" , msg, CWE_BUFFER_OVERRUN , certainty);
732739}
0 commit comments