Fixed #3161 (Show buffers size info for snprintf() buffer overruns)
This commit is contained in:
parent
d741f64256
commit
abd2525339
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue