From b9f4a773b880ed0edf51eb6f2d06b7b9a947916f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 25 Mar 2009 07:25:10 +0100 Subject: [PATCH] Buffer overrun: Added check to detect when size argument to memset is a char constant (#213) --- src/checkbufferoverrun.cpp | 21 ++++++++++++++++----- src/checkbufferoverrun.h | 2 ++ test/testbufferoverrun.cpp | 13 +++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index d90ec2643..f6a35d6c1 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -71,6 +71,11 @@ void CheckBufferOverrunClass::outOfBounds(const Token *tok, const std::string &w reportError(tok, "error", "outOfBounds", what + " is out of bounds"); } +void CheckBufferOverrunClass::sizeArgumentAsChar(const Token *tok) +{ + reportError(tok, "all", "sizeArgumentAsChar", "The size argument is given as a char constant"); +} + //--------------------------------------------------------------------------- @@ -163,13 +168,19 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co { if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets")) { - if (Token::Match(tok->next(), "( %varid% , %num% , %num% )", varid) || - Token::Match(tok->next(), "( %var% , %varid% , %num% )", varid)) + if (Token::Match(tok->next(), "( %varid% , %any% , %any% )", varid) || + Token::Match(tok->next(), "( %var% , %varid% , %any% )", varid)) { - const char *num = tok->strAt(6); - if (std::atoi(num) > total_size) + const Token *tokSz = tok->tokAt(6); + if (tokSz->str()[0] == '\'') + sizeArgumentAsChar(tok); + else if (tokSz->isNumber()) { - bufferOverrun(tok); + const char *num = tok->strAt(6); + if (std::atoi(num) > total_size) + { + bufferOverrun(tok); + } } } } diff --git a/src/checkbufferoverrun.h b/src/checkbufferoverrun.h index 03cd52d7e..f3fc9a38b 100644 --- a/src/checkbufferoverrun.h +++ b/src/checkbufferoverrun.h @@ -72,6 +72,7 @@ private: void bufferOverrun(const Token *tok); void strncatUsage(const Token *tok); void outOfBounds(const Token *tok, const std::string &what); + void sizeArgumentAsChar(const Token *tok); void getErrorMessages() { @@ -79,6 +80,7 @@ private: bufferOverrun(0); strncatUsage(0); outOfBounds(0, "index"); + sizeArgumentAsChar(0); } }; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 01457daff..b99c532f0 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -104,6 +104,8 @@ private: TEST_CASE(assign1); TEST_CASE(alloc); // Buffer allocated with new + + TEST_CASE(memset1); } @@ -577,6 +579,17 @@ private: "}\n"); ASSERT_EQUALS(std::string("[test.cpp:4]: (all) Array index out of bounds\n"), errout.str()); } + + + void memset1() + { + check("void foo()\n" + "{\n" + " char s[10];\n" + " memset(s, 5, '*');\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: (all) The size argument is given as a char constant\n"), errout.str()); + } }; REGISTER_TEST(TestBufferOverrun)