From 0cd2935dc7ffe38b5f487e238ec6e8be4c7cac64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 25 Dec 2019 09:23:07 +0100 Subject: [PATCH] Verification; Verify that function call argument values meet annotations --- lib/exprengine.cpp | 36 ++++++++++++++++++++++++++++++++++-- lib/exprengine.h | 2 +- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 593ddf027..71a9378b0 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -1601,9 +1601,41 @@ void ExprEngine::runChecks(ErrorLogger *errorLogger, const Tokenizer *tokenizer, parent = parent->astParent(); ++num; } - if (!parent || parent->str() != "(") + if (!parent || parent->str() != "(" || num == 0) return; + if (parent->astOperand1() && parent->astOperand1()->function()) { + const Variable *arg = parent->astOperand1()->function()->getArgumentVar(num - 1); + if (arg->nameToken()) { + std::string bad; + + MathLib::bigint low; + if (arg->nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, &low)) { + if (value.isLessThan(dataBase, low)) { + bad = "__cppcheck_low_(" + std::to_string(low) + ")"; + } + } + + MathLib::bigint high; + if (arg->nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, &high)) { + if (value.isLessThan(dataBase, low)) { + bad = "__cppcheck_low_(" + std::to_string(low) + ")"; + } + } + + if (!bad.empty()) { + dataBase->addError(tok->linenr()); + std::list callstack{tok}; + ErrorLogger::ErrorMessage errmsg(callstack, + &tokenizer->list, + Severity::SeverityType::error, + "verificationInvalidArgValue", + "There is function call, cannot determine that " + std::to_string(num) + getOrdinalText(num) + " argument value meets the attribute " + bad, CWE(0), false); + errorLogger->reportErr(errmsg); + } + } + } + // Check invalid function argument values.. for (const Library::InvalidArgValue &invalidArgValue : Library::getInvalidArgValues(settings->library.validarg(parent->astOperand1(), num))) { bool err = false; @@ -1640,7 +1672,7 @@ void ExprEngine::runChecks(ErrorLogger *errorLogger, const Tokenizer *tokenizer, if (err) { dataBase->addError(tok->linenr()); std::list callstack{tok}; - ErrorLogger::ErrorMessage errmsg(callstack, &tokenizer->list, Severity::SeverityType::error, "verificationInvalidArgValue", "There is function call, cannot determine that argument value is valid. Bad value: " + bad, CWE(0), false); + ErrorLogger::ErrorMessage errmsg(callstack, &tokenizer->list, Severity::SeverityType::error, "verificationInvalidArgValue", "There is function call, cannot determine that " + std::to_string(num) + getOrdinalText(num) + " argument value is valid. Bad value: " + bad, CWE(0), false); errorLogger->reportErr(errmsg); break; } diff --git a/lib/exprengine.h b/lib/exprengine.h index 84d665a43..aaceb0a33 100644 --- a/lib/exprengine.h +++ b/lib/exprengine.h @@ -253,7 +253,7 @@ namespace ExprEngine { bool isEqual(DataBase *dataBase, int value) const override; bool isGreaterThan(DataBase *dataBase, int value) const override; - virtual bool isLessThan(DataBase *dataBase, int value) const override; + bool isLessThan(DataBase *dataBase, int value) const override; std::string getExpr(DataBase *dataBase) const;