From 88840e6a0838ccca8b5b6f41c546581d5b8219a1 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sat, 27 Feb 2010 23:47:56 +0200 Subject: [PATCH] Fix #1453 (possible infinite loop processing GNU Go's engine/montecarlo.c) http://sourceforge.net/apps/trac/cppcheck/ticket/1453 --- lib/checkbufferoverrun.cpp | 29 ++++++++++++++++++++++++++++- test/testbufferoverrun.cpp | 31 +++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index f619a30bc..b0aaafbfa 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -149,6 +149,33 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok) // Check array usage.. //--------------------------------------------------------------------------- +/** + * @brief This is a helper class to be used with std::find_if + */ +class TokenStrEquals +{ +public: + /** + * @param str Token::str() is compared against this. + */ + TokenStrEquals(const std::string &str) + : value(str) + { + } + + /** + * Called automatically by std::find_if + * @param tok Token inside the list + */ + bool operator()(const Token *tok) const + { + return value == tok->str(); + } + +private: + const std::string value; +}; + void CheckBufferOverrun::checkScope(const Token *tok, const std::vector &varname, const int size, const int total_size, unsigned int varid) { std::string varnames; @@ -732,7 +759,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectornext() : 0; // Don't make recursive checking.. - if (std::find(_callStack.begin(), _callStack.end(), tok1) != _callStack.end()) + if (std::find_if(_callStack.begin(), _callStack.end(), TokenStrEquals(tok1->str())) != _callStack.end()) continue; // Check variable usage in the function.. diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 83262f869..efb982e92 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -143,6 +143,7 @@ private: TEST_CASE(terminateStrncpy1); TEST_CASE(terminateStrncpy2); + TEST_CASE(recursive_long_time); } @@ -1622,8 +1623,34 @@ private: ASSERT_EQUALS("[test.cpp:4]: (style) After a strncpy() the buffer should be zero-terminated\n", errout.str()); } - - + void recursive_long_time() + { + // Just test that recursive check doesn't take long time + check("char *f2 ( char *b )\n" + "{\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + " f2( b );\n" + "}\n" + "void f()\n" + "{\n" + " char a[10];\n" + " f2(a);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestBufferOverrun)