From d3c251f53afd1ace67480ba5d7912621b0bbf5a7 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Mon, 5 Apr 2010 21:47:50 +0300 Subject: [PATCH] Refactor and fix "After a strncpy() the buffer should be zero-terminated" checking, --- lib/checkbufferoverrun.cpp | 27 ++++++++++----------------- test/testbufferoverrun.cpp | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 72bb93912..9026c29fb 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -267,29 +267,22 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector_checkCodingStyle) { // check for strncpy which is not terminated - if (Token::Match(tok, "strncpy ( %varid% , %any% , %any% )", varid)) + if (Token::Match(tok, "strncpy ( %varid% , %any% , %num% )", varid)) { - const Token *tokSz = tok->tokAt(6); - if (tokSz->isNumber()) + // strncpy takes entire variable length as input size + if (MathLib::toLongNumber(tok->strAt(6)) == total_size) { - // strncpy takes entire variable length as input size - const std::string num = tok->strAt(6); - if (MathLib::toLongNumber(num) == total_size) + const Token *tok2 = tok->next()->link()->next(); + for (; tok2; tok2 = tok2->next()) { - const Token *tok2 = tok->next()->link()->next()->next(); - for (; tok2; tok2 = tok2->next()) + if (tok2->varId() == tok->tokAt(2)->varId()) { - if (Token::Match(tok2, "%varid%", tok->tokAt(2)->varId())) + if (!Token::Match(tok2, "%varid% [ %any% ] = 0 ;", tok->tokAt(2)->varId())) { - if (!Token::Match(tok2, "%varid% [ %any% ] = 0 ;", tok->tokAt(2)->varId())) - { - terminateStrncpyError(tok); - } - else - { - break; - } + terminateStrncpyError(tok); } + + break; } } } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 372821358..4dd369be6 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1775,6 +1775,21 @@ private: " bar[99] = 0;\n" "}\n"); ASSERT_EQUALS("[test.cpp:4]: (style) After a strncpy() the buffer should be zero-terminated\n", errout.str()); + + // Test with invalid code that there is no segfault + check("char baz[100];\n" + "strncpy(baz, \"var\", sizeof(baz))\n"); + ASSERT_EQUALS("", errout.str()); + + // Test that there are no duplicate error messages + check("void foo ( char *bar )\n" + "{\n" + " char baz[100];\n" + " strncpy(baz, bar, sizeof(baz));\n" + " foo(baz);\n" + " foo(baz);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (style) After a strncpy() the buffer should be zero-terminated\n", errout.str()); } void terminateStrncpy2()