From 4650e513e19f3b3fee7721c0fd69b1ce3c0ec29d Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Thu, 1 Oct 2009 11:33:53 +0300 Subject: [PATCH] Fix #741 (False positive: Buffer overrun with -a when index increased in multiple locations) http://sourceforge.net/apps/trac/cppcheck/ticket/741 --- src/checkbufferoverrun.cpp | 26 +++++++++++++++++ test/testbufferoverrun.cpp | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index ca090e893..06ddc6c3a 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -311,6 +311,32 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con if (!tok2 || !tok2->tokAt(5)) break; + // Check is the counter variable increased elsewhere inside the loop or used + // for anything else except reading + bool bailOut = false; + for (Token *loopTok = tok2->next(); loopTok && loopTok != tok2->next()->link(); loopTok = loopTok->next()) + { + if (loopTok->varId() == counter_varid) + { + // Counter variable used inside loop + if (Token::Match(loopTok->next(), "+=|-=|++|--|=")) + { + bailOut = true; + break; + } + else if (Token::Match(loopTok->previous(), "++|--")) + { + bailOut = true; + break; + } + } + } + + if (bailOut) + { + break; + } + std::ostringstream pattern; pattern << varnames << " [ " << strindex << " ]"; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 84fd3ad2f..9e6b84b6f 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -87,6 +87,7 @@ private: TEST_CASE(array_index_15); TEST_CASE(array_index_16); TEST_CASE(array_index_17); + TEST_CASE(array_index_18); TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_2); @@ -513,6 +514,64 @@ private: ASSERT_EQUALS("[test.cpp:5]: (possible error) Array index out of bounds\n", errout.str()); } + void array_index_18() + { + check("void f()\n" + "{\n" + " int a[5];\n" + " for (int i = 0; i < 6; i++)\n" + " {\n" + " a[i] = i;\n" + " i+=1;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " int a[5];\n" + " for (int i = 0; i < 6; i++)\n" + " {\n" + " a[i] = i;\n" + " i++;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " int a[5];\n" + " for (int i = 0; i < 6; i++)\n" + " {\n" + " a[i] = i;\n" + " ++i;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " int a[5];\n" + " for (int i = 0; i < 6; i++)\n" + " {\n" + " a[i] = i;\n" + " i=4;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " int a[6];\n" + " for (int i = 0; i < 7; i++)\n" + " {\n" + " a[i] = i;\n" + " i+=1;\n" + " }\n" + "}\n"); + TODO_ASSERT_EQUALS("[test.cpp:6]: (possible error) Buffer overrun\n", errout.str()); + } + void buffer_overrun_1() { check("void f()\n"