From 450442287cfa30f040ebb3d9dab0c0a405d2cedb Mon Sep 17 00:00:00 2001 From: Alexander Mai Date: Sun, 25 Aug 2013 18:46:07 +0200 Subject: [PATCH] Fixed #4974 (CheckBufferOverrun::writeOutsideBufferSize() too strict) --- lib/checkbufferoverrun.cpp | 3 ++- test/testbufferoverrun.cpp | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 8d011ce2a..e9e9b260e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -2239,6 +2239,7 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s // the number of bytes provided at the 3. parameter. // // References: +// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html // - http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_075.htm // - http://codewiki.wikidot.com/c:system-calls:write // ------------------------------------------------------------------------------------- @@ -2255,7 +2256,7 @@ void CheckBufferOverrun::writeOutsideBufferSize() if (Token::Match(tok, "pwrite|write (") && Token::Match(tok->tokAt(2)->nextArgument(), "%str% , %num%")) { const std::string & functionName(tok->str()); tok = tok->tokAt(2)->nextArgument(); // set tokenptr to %str% parameter - const std::size_t stringLength = Token::getStrLength(tok); + const std::size_t stringLength = Token::getStrLength(tok)+1; // zero-terminated string! tok = tok->tokAt(2); // set tokenptr to %num% parameter const MathLib::bigint writeLength = MathLib::toLongNumber(tok->str()); if (static_cast(writeLength) > stringLength) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 45873cd47..aafce26f5 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -4012,7 +4012,7 @@ private: check("void f(void){\n" "write(1, \"Dump string \\n\", 100);\n" "}"); // ^ number of bytes too big - ASSERT_EQUALS("[test.cpp:2]: (error) Writing 87 bytes outside buffer size.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (error) Writing 86 bytes outside buffer size.\n", errout.str()); check("void f(void){\n" "write(1, \"Dump string \\n\", 10);\n" @@ -4027,7 +4027,34 @@ private: "{\n" " write(p.i[1], \"\", 1);\n" "}"); + ASSERT_EQUALS("", errout.str()); + + check("static struct {\n" + " int i[2];\n" + "} p;\n" + "void foo()\n" + "{\n" + " write(p.i[1], \"\", 2);\n" + "}"); ASSERT_EQUALS("[test.cpp:6]: (error) Writing 1 bytes outside buffer size.\n", errout.str()); + // #4969 + check("void foo()\n" + "{\n" + " write(1, \"\\0\", 1);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // that is documented to be ok + check("void foo()\n" + "{\n" + " write(1, 0, 0);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // ... that is not ok + check("void foo()\n" + "{\n" + " write(1, 0, 1);\n" + "}"); + TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Writing 1 bytes outside buffer size.\n", "", errout.str()); } };