From 7c86a10a9df9b6fe4bbde7fa47f4fff4913b88b7 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Thu, 27 Aug 2009 00:17:32 +0700 Subject: [PATCH] Fixed #617 (False positive "buffer overrun" when sprintf() doesn't have optional parameters) http://sourceforge.net/apps/trac/cppcheck/ticket/617 --- src/checkbufferoverrun.cpp | 33 ++++++++++++++++++--------------- test/testbufferoverrun.cpp | 11 +++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 0def26a6c..d61a5d5a1 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -387,7 +387,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% [,)]", varid)) { int len = -2; - const Token *end = tok->next()->link(); // check format string const char *fmt = tok->strAt(4); @@ -412,26 +411,30 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con bufferOverrun(tok); } - // check arguments - len = 0; - for (const Token *tok2 = tok->tokAt(6); tok2 && tok2 != end; tok2 = tok2->next()) + // check arguments (if they exists) + if (tok->tokAt(5)->str() == ",") { - if (tok2->str()[0] == '\"') + len = 0; + const Token *end = tok->next()->link(); + for (const Token *tok2 = tok->tokAt(6); tok2 && tok2 != end; tok2 = tok2->next()) { - len -= 2; - const char *str = tok2->str().c_str(); - while (*str) + if (tok2->str()[0] == '\"') { - if (*str == '\\') + len -= 2; + const char *str = tok2->str().c_str(); + while (*str) + { + if (*str == '\\') + ++str; ++str; - ++str; - ++len; + ++len; + } } } - } - if (len >= (int)size) - { - bufferOverrun(tok); + if (len >= (int)size) + { + bufferOverrun(tok); + } } } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 0c7112886..440aea3e7 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -92,6 +92,7 @@ private: TEST_CASE(buffer_overrun_2); TEST_CASE(buffer_overrun_3); TEST_CASE(buffer_overrun_4); + TEST_CASE(buffer_overrun_5); TEST_CASE(sprintf1); TEST_CASE(sprintf2); @@ -546,6 +547,16 @@ private: ASSERT_EQUALS("", errout.str()); } + void buffer_overrun_5() + { + check("void f()\n" + "{\n" + " char n[5];\n" + " sprintf(n, \"d\");\n" + " printf(\"hello!\");\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } void sprintf1()