From bb115573f730d039fc5385a3a2496a3e6eff20a8 Mon Sep 17 00:00:00 2001 From: Ettl Martin Date: Mon, 11 Mar 2013 17:04:30 +0100 Subject: [PATCH] #4645 implemented new check: (POSIX) argument of function usleep() too big. --- lib/checkother.cpp | 34 ++++++++++++++++++++++++++++++++++ lib/checkother.h | 7 +++++++ test/testother.cpp | 15 +++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 041b3a5c2..ccff0c21c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -644,6 +644,40 @@ void CheckOther::checkPipeParameterSizeError(const Token *tok, const std::string "The variable '" + strVarName + "' is an array of size " + strDim + ", which does not match."); } +//----------------------------------------------------------------------------- +// check usleep(), which is allowed to be called with in a range of [0,1000000] +// +// Reference: +// - http://man7.org/linux/man-pages/man3/usleep.3.html +//----------------------------------------------------------------------------- +void CheckOther::checkSleepTimeInterval() +{ + if (!_settings->standards.posix) + return; + + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const std::size_t functions = symbolDatabase->functionScopes.size(); + for (std::size_t i = 0; i < functions; ++i) { + const Scope * scope = symbolDatabase->functionScopes[i]; + for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { + if (Token::Match(tok, "usleep ( %num% )")) { + const Token * const numTok = tok->tokAt(2); + MathLib::bigint value = MathLib::toLongNumber(numTok->str()); + if (value > 1000000) { + checkSleepTimeError(numTok, numTok->str()); + } + } + } + } +} + +void CheckOther::checkSleepTimeError(const Token *tok, const std::string &strDim) +{ + reportError(tok, Severity::error, + "tooBigSleepTime", "The argument of usleep must be less than 1000000.\n" + "The argument of usleep must be less than 1000000, but " + strDim + " is provided."); +} + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void CheckOther::checkSizeofForArrayParameter() diff --git a/lib/checkother.h b/lib/checkother.h index f9b2c38b5..e5960f4d5 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -120,6 +120,7 @@ public: checkOther.checkRedundantCopy(); checkOther.checkNegativeBitwiseShift(); checkOther.checkSuspiciousEqualityComparison(); + checkOther.checkSleepTimeInterval(); } /** To check the dead code in a program, which is inaccessible due to the counter-conditions check in nested-if statements **/ @@ -305,11 +306,15 @@ public: /** @brief %Check to avoid casting a return value to unsigned char and then back to integer type. */ void checkCastIntToCharAndBack(); + /** @brief %Check providing too big sleep time intervals on POSIX systems. */ + void checkSleepTimeInterval(); + private: bool isUnsigned(const Variable *var) const; bool isSigned(const Variable *var) const; // Error messages.. + void checkSleepTimeError(const Token *tok, const std::string &strDim); void checkCastIntToCharAndBackError(const Token *tok, const std::string &strFunctionName); void checkPipeParameterSizeError(const Token *tok, const std::string &strVarName, const std::string &strDim); void oppositeInnerConditionError(const Token *tok); @@ -403,6 +408,7 @@ private: c.invalidPointerCastError(0, "float", "double", false); c.negativeBitwiseShiftError(0); c.checkPipeParameterSizeError(0, "varname", "dimension"); + c.checkSleepTimeError(0,"dimension"); //performance c.redundantCopyError(0, "varname"); @@ -483,6 +489,7 @@ private: "* bitwise operation with negative right operand\n" "* provide wrong dimensioned array to pipe() system command (--std=posix)\n" "* cast the return values of getc(),fgetc() and getchar() to character and compare it to EOF\n" + "* provide too big sleep times on POSIX systems\n" //performance "* redundant data copying for const variable\n" diff --git a/test/testother.cpp b/test/testother.cpp index 81b89aba2..d4f3c6e7a 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -200,6 +200,8 @@ private: TEST_CASE(checkPipeParameterSize); // ticket #3521 TEST_CASE(checkCastIntToCharAndBack); // ticket #160 + + TEST_CASE(checkSleepTimeIntervall) } void check(const char code[], const char *filename = NULL, bool experimental = false, bool inconclusive = true, bool posix = false) { @@ -7330,7 +7332,20 @@ private: " }\n" "}"); ASSERT_EQUALS("", errout.str()); + } + void checkSleepTimeIntervall() { + // check usleep(), which is allowed to be called with in a range of [0,1000000] + check("void f(){\n" + "unsigned int Intervall = ;" + "usleep(10000);\n" + "}",NULL,false,false,true); + ASSERT_EQUALS("", errout.str()); + + check("void f(){\n" + "usleep(1000001);\n" + "}",NULL,false,false,true); + ASSERT_EQUALS("[test.cpp:2]: (error) The argument of usleep must be less than 1000000.\n", errout.str()); } };