Fixed #4974 (CheckBufferOverrun::writeOutsideBufferSize() too strict)

This commit is contained in:
Alexander Mai 2013-08-25 18:46:07 +02:00 committed by Daniel Marjamäki
parent acdbbeee44
commit 450442287c
2 changed files with 30 additions and 2 deletions

View File

@ -2239,6 +2239,7 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s
// the number of bytes provided at the 3. parameter. // the number of bytes provided at the 3. parameter.
// //
// References: // References:
// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
// - http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_075.htm // - http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_075.htm
// - http://codewiki.wikidot.com/c:system-calls:write // - 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%")) { if (Token::Match(tok, "pwrite|write (") && Token::Match(tok->tokAt(2)->nextArgument(), "%str% , %num%")) {
const std::string & functionName(tok->str()); const std::string & functionName(tok->str());
tok = tok->tokAt(2)->nextArgument(); // set tokenptr to %str% parameter 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 tok = tok->tokAt(2); // set tokenptr to %num% parameter
const MathLib::bigint writeLength = MathLib::toLongNumber(tok->str()); const MathLib::bigint writeLength = MathLib::toLongNumber(tok->str());
if (static_cast<std::size_t>(writeLength) > stringLength) if (static_cast<std::size_t>(writeLength) > stringLength)

View File

@ -4012,7 +4012,7 @@ private:
check("void f(void){\n" check("void f(void){\n"
"write(1, \"Dump string \\n\", 100);\n" "write(1, \"Dump string \\n\", 100);\n"
"}"); // ^ number of bytes too big "}"); // ^ 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" check("void f(void){\n"
"write(1, \"Dump string \\n\", 10);\n" "write(1, \"Dump string \\n\", 10);\n"
@ -4027,7 +4027,34 @@ private:
"{\n" "{\n"
" write(p.i[1], \"\", 1);\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()); 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());
} }
}; };