From c50f7787f90ecd44395f2fb1fae4f69ca3a37899 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sun, 30 Aug 2009 18:44:23 +0700 Subject: [PATCH] Fixed #569 (Buffer overrun not detected when strcat() called few times) http://sourceforge.net/apps/trac/cppcheck/ticket/569 --- src/checkbufferoverrun.cpp | 19 ++++++++++++++++++- test/testbufferoverrun.cpp | 11 +++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index ee54c603c..31d4a4fe8 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -352,8 +352,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con if (len >= static_cast(size)) { bufferOverrun(tok); + continue; } - continue; } @@ -374,6 +374,23 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con strncatUsage(tok->tokAt(9)); } + // Detect few strcat() calls + if (varid > 0 && Token::Match(tok, "strcat ( %varid% , %str% ) ;", varid)) + { + size_t charactersAppend = 0; + const Token *tok2 = tok; + + while (tok2 && Token::Match(tok2, "strcat ( %varid% , %str% ) ;", varid)) + { + charactersAppend += Token::getStrLength(tok2->tokAt(4)); + if (charactersAppend >= static_cast(size)) + { + bufferOverrun(tok2); + break; + } + tok2 = tok2->tokAt(7); + } + } // sprintf.. if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% [,)]", varid)) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 440aea3e7..d4babff2b 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -93,6 +93,7 @@ private: TEST_CASE(buffer_overrun_3); TEST_CASE(buffer_overrun_4); TEST_CASE(buffer_overrun_5); + TEST_CASE(buffer_overrun_6); TEST_CASE(sprintf1); TEST_CASE(sprintf2); @@ -558,6 +559,16 @@ private: ASSERT_EQUALS("", errout.str()); } + void buffer_overrun_6() + { + check("void f()\n" + "{\n" + " char n[5];\n" + " strcat(n, \"abc\");\n" + " strcat(n, \"def\");\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (possible error) Buffer overrun\n", errout.str()); + } void sprintf1() {