Fixed #3161 (Show buffers size info for snprintf() buffer overruns)

This commit is contained in:
Thomas Jarosch 2011-10-05 20:17:57 +02:00 committed by Daniel Marjamäki
parent d741f64256
commit abd2525339
3 changed files with 15 additions and 10 deletions

View File

@ -121,9 +121,14 @@ void CheckBufferOverrun::strncatUsageError(const Token *tok)
"strncat is to calculate remaining space in the buffer and use it as 3rd parameter."); "strncat is to calculate remaining space in the buffer and use it as 3rd parameter.");
} }
void CheckBufferOverrun::outOfBoundsError(const Token *tok, const std::string &what) void CheckBufferOverrun::outOfBoundsError(const Token *tok, const std::string &what, const bool show_size_info, const MathLib::bigint &supplied_size, const MathLib::bigint &actual_size)
{ {
reportError(tok, Severity::error, "outOfBounds", what + " is out of bounds"); std::ostringstream oss;
oss << what << " is out of bounds";
if (show_size_info)
oss << ": Supplied size " << supplied_size << " is larger than actual size of " << actual_size;
reportError(tok, Severity::error, "outOfBounds", oss.str());
} }
void CheckBufferOverrun::pointerOutOfBoundsError(const Token *tok, const std::string &object) void CheckBufferOverrun::pointerOutOfBoundsError(const Token *tok, const std::string &object)
@ -1070,7 +1075,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
{ {
const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4 + varc)); const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4 + varc));
if (n > total_size) if (n > total_size)
outOfBoundsError(tok->tokAt(4 + varc), "snprintf size"); outOfBoundsError(tok->tokAt(4 + varc), "snprintf size", true, n, total_size);
} }
// Check function call.. // Check function call..
@ -1096,7 +1101,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
if (pointerIsOutOfBounds && Token::Match(tok, "[;{}=] * %varid% [;=]", varid)) if (pointerIsOutOfBounds && Token::Match(tok, "[;{}=] * %varid% [;=]", varid))
{ {
outOfBoundsError(tok->tokAt(2), tok->strAt(2)); outOfBoundsError(tok->tokAt(2), tok->strAt(2), false, 0, 0);
} }
} }
} }
@ -1321,7 +1326,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
{ {
const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4)); const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4));
if (n > total_size) if (n > total_size)
outOfBoundsError(tok->tokAt(4), "snprintf size"); outOfBoundsError(tok->tokAt(4), "snprintf size", true, n, total_size);
} }
// undefined behaviour: result of pointer arithmetic is out of bounds // undefined behaviour: result of pointer arithmetic is out of bounds

View File

@ -225,7 +225,7 @@ public:
void arrayIndexOutOfBoundsError(const std::list<const Token *> &callstack, const ArrayInfo &arrayInfo, const std::vector<MathLib::bigint> &index); void arrayIndexOutOfBoundsError(const std::list<const Token *> &callstack, const ArrayInfo &arrayInfo, const std::vector<MathLib::bigint> &index);
void bufferOverrunError(const Token *tok, const std::string &varnames = ""); void bufferOverrunError(const Token *tok, const std::string &varnames = "");
void strncatUsageError(const Token *tok); void strncatUsageError(const Token *tok);
void outOfBoundsError(const Token *tok, const std::string &what); void outOfBoundsError(const Token *tok, const std::string &what, const bool show_size_info, const MathLib::bigint &supplied_size, const MathLib::bigint &actual_size);
void sizeArgumentAsCharError(const Token *tok); void sizeArgumentAsCharError(const Token *tok);
void terminateStrncpyError(const Token *tok, const std::string &varname); void terminateStrncpyError(const Token *tok, const std::string &varname);
void bufferNotZeroTerminatedError(const Token *tok, const std::string &varname, const std::string &function); void bufferNotZeroTerminatedError(const Token *tok, const std::string &varname, const std::string &function);
@ -243,7 +243,7 @@ public:
c.arrayIndexOutOfBoundsError(0, ArrayInfo(0, "array", 1, 2), indexes); c.arrayIndexOutOfBoundsError(0, ArrayInfo(0, "array", 1, 2), indexes);
c.bufferOverrunError(0, std::string("buffer")); c.bufferOverrunError(0, std::string("buffer"));
c.strncatUsageError(0); c.strncatUsageError(0);
c.outOfBoundsError(0, "index"); c.outOfBoundsError(0, "index", true, 2, 1);
c.sizeArgumentAsCharError(0); c.sizeArgumentAsCharError(0);
c.terminateStrncpyError(0, "buffer"); c.terminateStrncpyError(0, "buffer");
c.bufferNotZeroTerminatedError(0, "buffer", "strncpy"); c.bufferNotZeroTerminatedError(0, "buffer", "strncpy");

View File

@ -2601,7 +2601,7 @@ private:
" char str[5];\n" " char str[5];\n"
" snprintf(str, 10, \"%s\", \"abc\");\n" " snprintf(str, 10, \"%s\", \"abc\");\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) snprintf size is out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) snprintf size is out of bounds: Supplied size 10 is larger than actual size of 5\n", errout.str());
} }
void snprintf2() void snprintf2()
@ -2642,7 +2642,7 @@ private:
" struct Foo x;\n" " struct Foo x;\n"
" snprintf(x.a, 2, \"aa\");\n" " snprintf(x.a, 2, \"aa\");\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) snprintf size is out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) snprintf size is out of bounds: Supplied size 2 is larger than actual size of 1\n", errout.str());
check("struct Foo { char a[1]; };\n" check("struct Foo { char a[1]; };\n"
"void f()\n" "void f()\n"
@ -2651,7 +2651,7 @@ private:
" snprintf(x.a, 2, \"aa\");\n" " snprintf(x.a, 2, \"aa\");\n"
" free(x);\n" " free(x);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) snprintf size is out of bounds\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) snprintf size is out of bounds: Supplied size 2 is larger than actual size of 1\n", errout.str());
check("struct Foo { char a[1]; };\n" check("struct Foo { char a[1]; };\n"
"void f()\n" "void f()\n"