diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 9c1f751aa..f4390b481 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -804,18 +804,26 @@ void CheckBufferOverrun::argumentSize() err = true; } if (err) - argumentSizeError(tok, tok->str(), argument->name()); + argumentSizeError(tok, tok->str(), paramIndex, callargs[paramIndex]->expressionString(), calldata->variable(), argument); } } } } -void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &functionName, const std::string &varname) +void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &functionName, nonneg int paramIndex, const std::string ¶mExpression, const Variable *paramVar, const Variable *functionArg) { - reportError(tok, Severity::warning, "argumentSize", + const std::string strParamNum = std::to_string(paramIndex + 1) + getOrdinalText(paramIndex + 1); + ErrorPath errorPath; + errorPath.emplace_back(tok, "Function '" + functionName + "' is called"); + if (functionArg) + errorPath.emplace_back(functionArg->nameToken(), "Declaration of " + strParamNum + " function argument."); + if (paramVar) + errorPath.emplace_back(paramVar->nameToken(), "Passing buffer '" + paramVar->name() + "' to function that is declared here"); + errorPath.emplace_back(tok, ""); + + reportError(errorPath, Severity::warning, "argumentSize", "$symbol:" + functionName + '\n' + - "$symbol:" + varname + '\n' + - "The array '" + varname + "' is too small, the function '" + functionName + "' expects a bigger one.", CWE_ARGUMENT_SIZE, Certainty::normal); + "Buffer '" + paramExpression + "' is too small, the function '" + functionName + "' expects a bigger buffer in " + strParamNum + " argument", CWE_ARGUMENT_SIZE, Certainty::normal); } //--------------------------------------------------------------------------- diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 875679dd5..7f02f3457 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -85,7 +85,7 @@ public: c.arrayIndexThenCheckError(nullptr, "i"); c.bufferOverflowError(nullptr, nullptr, Certainty::normal); c.objectIndexError(nullptr, nullptr, true); - c.argumentSizeError(nullptr, "function", "buffer"); + c.argumentSizeError(nullptr, "function", 1, "buffer", nullptr, nullptr); } /** @brief Parse current TU and extract file info */ @@ -117,7 +117,7 @@ private: void terminateStrncpyError(const Token *tok, const std::string &varname); void argumentSize(); - void argumentSizeError(const Token *tok, const std::string &functionName, const std::string &varname); + void argumentSizeError(const Token *tok, const std::string &functionName, nonneg int paramIndex, const std::string ¶mExpression, const Variable *paramVar, const Variable *functionArg); void objectIndex(); void objectIndexError(const Token *tok, const ValueFlow::Value *v, bool known); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index f1ad29a02..b314af3aa 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2862,26 +2862,40 @@ private: } void buffer_overrun_function_array_argument() { + setMultiline(); + check("void f(char a[10]);\n" "void g() {\n" " char a[2];\n" " f(a);\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str()); + ASSERT_EQUALS("test.cpp:4:warning:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n" + "test.cpp:4:note:Function 'f' is called\n" + "test.cpp:1:note:Declaration of 1st function argument.\n" + "test.cpp:3:note:Passing buffer 'a' to function that is declared here\n" + "test.cpp:4:note:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n", errout.str()); check("void f(float a[10][3]);\n" "void g() {\n" " float a[2][3];\n" " f(a);\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str()); + ASSERT_EQUALS("test.cpp:4:warning:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n" + "test.cpp:4:note:Function 'f' is called\n" + "test.cpp:1:note:Declaration of 1st function argument.\n" + "test.cpp:3:note:Passing buffer 'a' to function that is declared here\n" + "test.cpp:4:note:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n", errout.str()); check("void f(int a[20]);\n" "void g() {\n" " int a[2];\n" " f(a);\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str()); + ASSERT_EQUALS("test.cpp:4:warning:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n" + "test.cpp:4:note:Function 'f' is called\n" + "test.cpp:1:note:Declaration of 1st function argument.\n" + "test.cpp:3:note:Passing buffer 'a' to function that is declared here\n" + "test.cpp:4:note:Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument\n", errout.str()); check("void f(int a[]) {\n" " switch (2) {\n"