From abd2525339190a3f5445f88956dc4e514a6b7f48 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Wed, 5 Oct 2011 20:17:57 +0200 Subject: [PATCH] Fixed #3161 (Show buffers size info for snprintf() buffer overruns) --- lib/checkbufferoverrun.cpp | 15 ++++++++++----- lib/checkbufferoverrun.h | 4 ++-- test/testbufferoverrun.cpp | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index f0c83513e..ce9d5adce 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -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."); } -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) @@ -1070,7 +1075,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectorstrAt(4 + varc)); 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.. @@ -1096,7 +1101,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectortokAt(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)); 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 diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 389d36220..9bc1e69f6 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -225,7 +225,7 @@ public: void arrayIndexOutOfBoundsError(const std::list &callstack, const ArrayInfo &arrayInfo, const std::vector &index); void bufferOverrunError(const Token *tok, const std::string &varnames = ""); 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 terminateStrncpyError(const Token *tok, const std::string &varname); 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.bufferOverrunError(0, std::string("buffer")); c.strncatUsageError(0); - c.outOfBoundsError(0, "index"); + c.outOfBoundsError(0, "index", true, 2, 1); c.sizeArgumentAsCharError(0); c.terminateStrncpyError(0, "buffer"); c.bufferNotZeroTerminatedError(0, "buffer", "strncpy"); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index b4545bb69..11c944531 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2601,7 +2601,7 @@ private: " char str[5];\n" " snprintf(str, 10, \"%s\", \"abc\");\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() @@ -2642,7 +2642,7 @@ private: " struct Foo x;\n" " snprintf(x.a, 2, \"aa\");\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" "void f()\n" @@ -2651,7 +2651,7 @@ private: " snprintf(x.a, 2, \"aa\");\n" " free(x);\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" "void f()\n"